2012-04-24 5 views
2

У меня есть родительский класс, который принимает две ссылки, которые могут или не могут быть ссылками на одно и то же. В этом случае, если они такие же, я получаю предупреждение точку последовательности в списке инициализатора моего ребенка класса:Предупреждение о последовательности в списке инициализаторов

class A 
{ 
    public: 
    A(int) {} 
    private: 
    A() {} 
}; 

class Parent 
{ 
    public: 
    Parent(A&, A&) {} 
}; 

class Child : public Parent 
{ 
    public: 
    Child() : 
     Parent(
      *(_A = new A(0)), 
      *(_A)) //Warning on this line 
    { 
    } 

    private: 
    A *_A; 
}; 

int main(int argc, char** argv) 
{ 
    return 0; 
} 

Я предполагаю, что это потому, что разыменования на этой линии не гарантируется происходит после того, как память была выделена. Независимо от того, мой вопрос в том, есть ли все равно вокруг этого без внесения изменений ни в Родитель, ни в A?

ответ

4

Вы правы, порядок, в котором вызываются два аргумента родительского конструктора, не гарантируется (между ними нет точки последовательности), поэтому компилятор может юридически оценить *(_A), прежде чем он оценит *(_A = new A(0)).

Нужно ли динамически выделять A? Если вы не можете сделать:

class Child : public Parent 
{ 
    public: 
    Child() : Parent(_a, _a), _a(0) {} 
    private: 
    A _a;    // _A is reserved for the implementation (compiler + library) 
}; 

С одной оговоркой, в то время как он действует, чтобы получить адрес члена или взять справку в него, это не определено поведение использования, что ссылка или указатель перед _a член инициализируется, что произойдет только после завершения конструктора Parent. То есть до тех пор, пока конструктор Parent сохраняет только ссылку, но не использует объект, в котором вы находитесь в безопасности (по краю лезвия, но без кровотечения).

Если Parent конструктор использует ссылку на что-нибудь другое, чем хранить его, вы можете изменить Child класс получить указатель на уже построенный A объект:

Child::Child(A* a) : Parent(*a, *a), _a(a) {}