one_eight_seven 3 4 октября, 2019 Опубликовано 4 октября, 2019 (изменено) · Жалоба 18 minutes ago, jcxz said: Так покажите как? Кроме тех методов что уже предложены. #include <iostream> class Base { public: Base() {} ~Base() {} void * m_array[13]; }; class Derived : public Base { public: Derived() {} ~Derived() {} /* Just for lulz */ void ** get_base_array_pointer (void) { return Base::m_array; } void ** get_derived_array_pointer (void) { return this->m_array; } }; int main(){ Derived tst_obj; std::cout << "Derived class array pointer address (via access) is:" << std::hex << size_t(tst_obj.m_array) << std::endl; std::cout << "Derived class array pointer address (via method) is:" << std::hex << size_t(tst_obj.get_base_array_pointer()) << std::endl; std::cout << "Base class array pointer address (via method) is:" << std::hex << size_t(tst_obj.get_derived_array_pointer()) << std::endl; Base * p = &tst_obj; p->m_array[12] = NULL; std::cout << "element is is:" << std::hex << size_t(tst_obj.m_array[12]) << std::endl; tst_obj.m_array[12] = (void*)42; std::cout << "element is is:" << std::hex << size_t(p->m_array[12]) << std::endl; } Результат: $ g++ tst.cpp $ ./a.out Derived class array pointer address (via access) is:7ffef69e5680 Derived class array pointer address (via method) is:7ffef69e5680 Base class array pointer address (via method) is:7ffef69e5680 element is is:0 element is is:2a Вызов приложения после компиляции пропал. Его съел элемент форума Code. Изменено 4 октября, 2019 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 1 hour ago, jcxz said: А в дочерних классах объявляйте указатель на этот массив. Но как в дочерхних классах его заполнить? В базовом классе не соберётся метод OpenAllDrivers, т.к. размер массива неизвестен. 48 minutes ago, Forger said: Простой односвязный список. Т.е. примерно я думал в правильном направлении. Значит ничего такого из нового стандарта нельзя использовать(( Ну тогда шаблончики вступают в работу) 24 minutes ago, one_eight_seven said: Его нельзя перегружать. Перегружаются методы. Нет, давайте об очевидных вещам не будем говорить. Это всё понятно. Я же привёл псевдокод, о чём честно и сообщил в стартовом сообщении. Пусть это будет не массив, а некий std::tuple, или ещё что-то, мне всё равно. Мне нужно, чтобы выполнялись три требования, которые я тоже перечислил в стартовом сообщении. 20 minutes ago, Forger said: После этого можно смело переходить на старый добрый C Угу, а мы от этого уходим. 9 minutes ago, one_eight_seven said: void * m_array[13]; А почему 13? А если я захочу 24 драйвера туда занести? Или 1? В первом случае будет недабор памяти, а во втором - перебор) Я ищу что-то такое, что легко масштабируется, не привязано к конкретному типу данных (это не проблема, просто упомянул), и кушает памяти ровно столько, сколько нужно. Пока да, односвязный списко лидирует. Он конечно содержит небольшой оверхэд из-за указателей, но по-другому и не сделаешь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 187 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба А какой смысл в этих?: 10 минут назад, one_eight_seven сказал: void ** get_base_array_pointer (void) { return Base::m_array; } void ** get_derived_array_pointer (void) { return this->m_array; } Через указатель на базовый тип с потомками работать невозможно. И зачем тогда вообще нужны эти get_base_array_pointer и get_derived_array_pointer??? И это ещё кроме того, что оба они будут возвращать одно и то же значение: указатель на Base::m_array. И зачем это??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 4 октября, 2019 Опубликовано 4 октября, 2019 (изменено) · Жалоба 3 minutes ago, jcxz said: Через указатель на базовый тип с потомками работать невозможно. В коде же работает. Quote И зачем тогда вообще нужны эти get_base_array_pointer и get_derived_array_pointer??? Написано же just for lulz. для тех, кто не понимает, что массив, объявленный в базовом классе - это тот же массив, что и в наследующем. Quote И это ещё кроме того, что оба они будут возвращать одно и то же значение: указатель на Base::m_array. Собственно, это и демонстрируется. Если хочется другого и без "не надо говорить очевидные вещи", так прекращайте говорить на омском языке, и излагайте мысли на русском. Топикстартеру: Если размер массива заранее неизвестен, то в базовом классе можно объявить два виртуальных (можно и чистых виртуальных) метода - взятия массива и его размера. И эти методы переопределить в наследующих классах (их можно сделать хоть публичными, хоть защищёнными, хоть приватными). А сам массив объявлять и определять в дочерних. Или с VMT тоже не хочется связываться? Изменено 4 октября, 2019 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 187 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 3 минуты назад, haker_fox сказал: Но как в дочерхних классах его заполнить? В базовом классе не соберётся метод OpenAllDrivers, т.к. размер массива неизвестен. Кого заполнить? Массив или указатели на него? Если первое - он у вас будет static в каждом дочернем - свой. Инициализируется отдельно в .cpp-файле как все static-данные. Указатель на массив - инициализируется в конструкторе дочернего класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 2 minutes ago, haker_fox said: Угу, а мы от этого уходим. Оно и видно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 187 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 1 минуту назад, one_eight_seven сказал: В коде же работает. У Вас там нет замены родительского массива на дочерние. Т.е. - того что нужно ТС. А тот код что Вы привели - бессмысленный. 1 минуту назад, one_eight_seven сказал: Написано же just for lulz. для тех, кто не понимает, что массив, объявленный в базовом классе - это тот же массив, что и в наследующем. ТСу было нужно другое. Ему нужен был свой экземпляр массива в каждом дочернем классе. Т.е. - собственно перегрузка массивов. Как для функций. 3 минуты назад, one_eight_seven сказал: Если хочется другого и без "не надо говорить очевидные вещи", так прекращайте говорить на омском языке, и излагайте мысли на русском. Вам бы я порекомендовал читать исходный вопрос. Прежде чем отвечать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 1 minute ago, Forger said: Оно и видно :) Простите?) 1 minute ago, jcxz said: Ему нужен был свой экземпляр массива в каждом дочернем классе. Не совсем. Нужна подмена. Т.е. массив должен быть один в итоге. 4 minutes ago, jcxz said: Если первое - он у вас будет static в каждом дочернем - свой. А как же с ним будут работать функции базового класса? Которые в дочерних классах не перегружены. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 2 minutes ago, jcxz said: Вам бы я порекомендовал читать исходный вопрос. Прежде чем отвечать. Прочитал. Массив родительского класса изменяется в дочернем. Размер определён и соберётся во время компиляции. Если в конструктор добавить инициализацию полей - тоже будет сделано компилятором. Никакого динамического создания. Всё по ТЗ. 13 minutes ago, haker_fox said: А почему 13? А если я захочу 24 драйвера туда занести? Или 1? В первом случае будет недабор памяти, а во втором - перебор) Я ищу что-то такое, что легко масштабируется, не привязано к конкретному типу данных (это не проблема, просто упомянул), и кушает памяти ровно столько, сколько нужно. Пока да, односвязный списко лидирует. Он конечно содержит небольшой оверхэд из-за указателей, но по-другому и не сделаешь. Показать по-другому? Quote В базовом классе не соберётся метод OpenAllDrivers Его нет в базовом. Он у вас появляется в дочернем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 8 minutes ago, haker_fox said: Простите?) Речь про код в первом посте на этой странице. Возвращать указатель на внутренние данные класса и наличие двойного указателя в плюсах - это вообще тотальный уход в С. К чему тут С++ и уж тем более С++17 - вообще загадка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 6 minutes ago, one_eight_seven said: Размер определён и соберётся во время компиляции. Как же он определён? 6 minutes ago, one_eight_seven said: Показать по-другому? Да. 7 minutes ago, one_eight_seven said: Размер определён и соберётся во время компиляции. Вы его задаёте "в лоб", указывая размер. А мне нужно, чтобы размер был рассчитан самим компилятором на этапе сборки. Я думал, это следует из комментария к массиву для базового класса и псевдокода дочернего класса. 4 minutes ago, Forger said: Речь про код в первом посте на этой странице. В первом посте мой код. Там нет никаких двойных указателей. И они тем более не возвращаются. Вы наверно о коде @one_eight_seven говорите... 12 minutes ago, one_eight_seven said: Его нет в базовом. Он у вас появляется в дочернем. Сейчас возможности проверить нет. Но что-то тут не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 5 minutes ago, haker_fox said: . Вы наверно о коде @one_eight_seven говорите... Ну да: )) 6 minutes ago, Forger said: Речь про код в первом посте на этой странице. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 10 minutes ago, haker_fox said: Да. #include <iostream> using namespace std; class Base { public: Base() {} ~Base() {} void open_all_drivers() { size_t size = get_size(); int * p = get_array(); for (size_t i = 0; i<size; ++i){ cout << dec << i << "'th element is: " << hex << p[i] << endl; } } private: virtual int * get_array() = 0; virtual int get_size() = 0; }; class Derived : public Base { public: Derived() { size_t size = get_size(); int * p = get_array(); for (size_t i = 0; i<size; ++i){ p[i] = 0x100 + i; } } ~Derived() {} private: int m_array[12]; virtual int * get_array() final { return m_array; } virtual int get_size() final { return sizeof(m_array)/sizeof(int); } }; static Derived tst; int main(){ Base * p = &tst; p->open_all_drivers(); return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба @one_eight_seven, уже понятнее. Но! Задача решена хоть и через классы, но по-сути используя сишные указатели...((( Мне нужно было красивое решение. Согласен, термин нетехническй. Но я привёл ссылку на хабру, где коллега с нашего сайта использовал tuple. Получилось очень красиво... Я имел в виду что-то подобное из нового стандарта. И это я написал явно... Все эти тасования указателей - действительно возврат к Си, хоть и спрятанный за классами. Простите, что резковато. Но вы не совсем уловили то, что мне нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 4 октября, 2019 Опубликовано 4 октября, 2019 · Жалоба 11 minutes ago, haker_fox said: Вы его задаёте "в лоб", указывая размер. А мне нужно, чтобы размер был рассчитан самим компилятором на этапе сборки. Я думал, это следует из комментария к массиву для базового класса и псевдокода дочернего класса. Компилятор не будет рассчитывать, более того, код типа: type * m_array[] -- это, на самом деле type* m_array[0]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться