Ваш замысел недостаточно ясен, поэтому авторы других ответов запутались в своих ответах.
В вашем коде вы, кажется, делаете вызовы AddToChildren
от одних конструкторов, но не от других. Например, у вас есть список children
в A
, но вы никогда не вызываете конструктор AddToChildren
из A::A
. Кроме того, у класса C
нет собственного списка children
. Зачем? Предполагается ли поделиться списком children
с B
?
Я могу предположить, что тот факт, что вы не вызываете AddToChildren
из всех конструкторов, означает, что некоторые конструкторы предназначены для создания полных "объектов" данного типа (эти конструкторы действительно вызывают AddToChildren
), в то время как некоторые другие конструкторы предназначен для использования в качестве «промежуточных» конструкторов классами-потомками (эти конструкторы не вызывают AddToChildren
).
Такой дизайн может показаться весьма сомнительным и подверженным ошибкам. Обратите внимание, например, что C::C
вызывает AddToChildren
, который предположительно добавляет this
к B::children
(было ли это намерением?), А также вызывает конструктор B::B
, который также добавит this
к B::children
. Таким образом, одно и то же значение this
добавляется в список дважды. Это, кажется, не имеет никакого смысла.
Вам нужно выяснить, что именно вы пытаетесь сделать, а затем исправить свой дизайн. Как только вы закончите с этим, вы можете «виртуализировать» список, используя технику, предложенную Нилом (представляя виртуальный метод GetList
). Нил позже написал неправильно, что это не будет работать. На самом деле, он будет отлично работать (опять же, при условии, что я правильно понял ваш замысел).
(с учетом уточняющих комментариев ФП)
Итак, вы хотите, чтобы B
объекты добавлялись в список A::children
, а C
объекты добавлялись в списки A::children
и B::children
. Это может быть достигнуто с помощью
class A {
...
int a;
static vector<A*> children;
...
A(int a) : a(a) {}
virtual vector<A*> *GetList() = 0;
void AddToChildren(A* obj) { // note: non-virtual
GetList()->push_back(obj);
}
...
};
class B : public A {
...
int b;
static vector<A*> children;
...
B(int a, int b) : b(b), A(a) {
AddToChildren(this);
}
virtual vector<A*> *GetList() {
return &A::children;
}
...
};
class C : public B {
...
int c;
...
C(int a, int b, int c) : c(c), B(a,b) {
AddToChildren(this);
};
virtual vector<A*> *GetList() {
return &B::children;
}
...
};
Обратите внимание, что, несмотря на то, что было сказано другими авторами, здесь работают виртуальные вызовы, и они работают именно так, как они нужны нам для достижения запрошенной функциональности. Обратите внимание, что в этом случае нет смысла делать метод AddToChildren
виртуальным, достаточно виртуальности только GetList
.
Кроме того, все это мало что дает, если AddToChildren
просто делает push_back
. Нет особого смысла строить такую инфраструктуру только для таких "тонких" AddToChildren
. Просто делайте то, что вы хотите сделать явно в каждом конструкторе.