class Lol
{
int Data[10];
public:
Lol();
void setDataSlot(int I,int N){Data[I] = N;}
int getDataSlot(int I){return Data[I];}
void setNullData(int I){Data[I] = 0;}
};
Lol::Lol(){}
Lol All[10];
0.Выгодно делать прототипы методов или полностью описывать внутри класса?
1.Как при этом будет для массива распределяться память?
1.1. Если я не определяю прототипы, значит ли это что массив All в каждой ячейке содержит те же методы что и другие ячейки, или
ссылается на оригинальный метод?(своеобразный static).
Здравствуйте, Ubi, Вы писали:
Ubi>0.Выгодно делать прототипы методов или полностью описывать внутри класса? Ubi>1.Как при этом будет для массива распределяться память?
Не-виртуальные методы не занимают память в объекте или в массиве объектов.
Наличие виртуальных методов, независимо от их количества, обычно увеличивает размер объекта на один указатель (который указывает на таблицу виртуальных методов).
Здравствуйте, Pzz, Вы писали:
Pzz>А как они могут знать, что виртуализация не понадобится в производном классе? Так что боюсь, место под указатель все равно придется завести.
В принципе вторая фаза компилятора (вызываемая из линкера) владеет уже всей информацией о всех классах.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В принципе вторая фаза компилятора (вызываемая из линкера) владеет уже всей информацией о всех классах.
Ещё есть ddl-ки/SO-шки...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Pavel Dvorkin, Вы писали:
Pzz>>А как они могут знать, что виртуализация не понадобится в производном классе? Так что боюсь, место под указатель все равно придется завести.
PD>В принципе вторая фаза компилятора (вызываемая из линкера) владеет уже всей информацией о всех классах.
А это существует где-либо, кроме как в диссертациях по computer science?
PD>>В принципе вторая фаза компилятора (вызываемая из линкера) владеет уже всей информацией о всех классах.
Pzz>А это существует где-либо, кроме как в диссертациях по computer science?
Что именно ? Вторая фаза ? Да, это c2.dll из Visual Studio.
Здравствуйте, Erop, Вы писали:
PD>>В принципе вторая фаза компилятора (вызываемая из линкера) владеет уже всей информацией о всех классах.
E>Ещё есть ddl-ки/SO-шки...
Можно (опять же в принципе) оставить vtable для экспортируемых классов. Для остальных наследовать некому.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Можно (опять же в принципе) оставить vtable для экспортируемых классов. Для остальных наследовать некому.
Ну, например,
struct IDeletable {
virtual ~IDeletable() {}
};
экспортируемый или нет?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Этот нет (Visual Studio). Для экспорта нужно __declspec(dllexport). Если хочешь сказать , что __declspec(dllexport) может быть у наследников, которые экспортируются — верно, но поскольку сам тип IDeletable за пределами DLL не виден, то только для наследников и нужна vtable, а вызов именно этого деструктора по иерархии можно реализовать и прямо из всех непосредственных наследников.
Здесь создается виртуальный экспортируемый деструктор, который внутри вызывает, как обычно, IDeletable::~IDeletable, но тот не экспортируемый, а поэтому его вызов можно реализовать и напрямую.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, niXman, Вы писали:
X>>а clang и gcc научились девиртуализировать методы там, где виртуализация не нужна.
Pzz>А как они могут знать, что виртуализация не понадобится в производном классе?
Есть final в С++11. И sealed в MSVС с тем же смыслом.
Не уверен, используют ли его компиляторы для девиртуализации, но могут же.
A popular way to achieve modular design is via indirect calls:
* putting functions in other modules/compilation units
* functions pointers in C (a la qsort), lambas in C++11
* virtual functions in C++
(+ ещё в паре мест подобное)
Это они что имеют ввиду?
Вызов лямбды через func ptr (когда возможно) или через type-erasure (a-la std::function-like)? Так к самим лямбдам это ортогонально
EP>A popular way to achieve modular design is via indirect calls:
EP>* putting functions in other modules/compilation units
EP>* functions pointers in C (a la qsort), lambas in C++11
EP>* virtual functions in C++
EP>(+ ещё в паре мест подобное)
EP>Это они что имеют ввиду? EP>Вызов лямбды через func ptr (когда возможно) или через type-erasure (a-la std::function-like)? Так к самим лямбдам это ортогонально
Под indirect calls имели в виду вирутальные функции. Lambdas, так же как и указатели на функции, могут быть переданы другим алгоритмам. Все это про модульность в смысле создания независимых кусков, реализующих некую функциональность. По-моему, никаких тонких мыслей подводных камнет здесь нет.
Здравствуйте, andyp, Вы писали:
A>Под indirect calls имели в виду вирутальные функции. Lambdas, так же как и указатели на функции, могут быть переданы другим алгоритмам. Все это про модульность в смысле создания независимых кусков, реализующих некую функциональность. По-моему, никаких тонких мыслей подводных камнет здесь нет.
Допустим на этом слайде действительно подразумевалась только модульность, без относительно оверхеда.
Но там же дальше слайд №5:
Isn't modularity a performance-killer?
a popular way to achieve modular design is via indirect calls
— putting functions in other modules/compilation units
— functions pointers in C (a la qsort)
— lambdas in C++11
— virtual functions in C++
generally, the overhead is not noticeable at system level
the overhead goes beyond the lack of simple inlining
— compile-time math cannot happen
— call-graph re-ordering cannot happen
— constant-propagation cloning cannot happen
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, andyp, Вы писали:
A>>Под indirect calls имели в виду вирутальные функции. Lambdas, так же как и указатели на функции, могут быть переданы другим алгоритмам. Все это про модульность в смысле создания независимых кусков, реализующих некую функциональность. По-моему, никаких тонких мыслей подводных камнет здесь нет.
EP>Допустим на этом слайде действительно подразумевалась только модульность, без относительно оверхеда. EP>Но там же дальше слайд №5: EP>
EP>Isn't modularity a performance-killer?
EP>
a popular way to achieve modular design is via indirect calls
EP>- putting functions in other modules/compilation units
EP>- functions pointers in C (a la qsort)
EP>- lambdas in C++11
EP>- virtual functions in C++
EP> generally, the overhead is not noticeable at system level
EP> the overhead goes beyond the lack of simple inlining
EP>- compile-time math cannot happen
EP>- call-graph re-ordering cannot happen
EP>- constant-propagation cloning cannot happen
Согласен, тут у них нечто немного шизофреническое написано. Сначала утверждают, что оверхед за счет модульности — ерунда и в общем случае незаметен, а затем пишут, насколько и как он мешает оптимизации . И да, если лямбду можно заинлайнить в месте вызова, то непонятно, как это все относится к ней.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Этот нет (Visual Studio). Для экспорта нужно __declspec(dllexport). Если хочешь сказать , что __declspec(dllexport) может быть у наследников, которые экспортируются — верно, но поскольку сам тип IDeletable за пределами DLL не виден
В каком смысле "не виден"?
Попробуй сделать такую dll, возьми её хедер, отнаследуйся в exe, и погляди виден или нет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском