2012-01-12 2 views
0

Вот два классаразница между конструкторами с параметрами и без

class A 
{ 
    std::string s; 
public: 
    A() { prn("A constructor"); } 
    A(std::string s) : s(s) { prn("A not empty constructor"); } 
    A(const A&) { prn("A copy constructor"); } 
    A& operator =(const A& a) { prn("A = operator"); return *this; } 
    void p() { prn("in A"); } 
}; 

class B 
{ 
public: 
    A a; 
    B(A aa) : a(aa) { prn("B constructor"); } 
    B() { prn("B default constructor"); } 
}; 

Теперь следующий код работает правильно

B b(A("sa")); 
b.a.p(); 

Печать:

А, не пустой конструктор
копия конструктора
B конструктор в A

Но если я использую конструктор без параметров происходит нечто странное

B b(A()); 

компилирует и бежать, но нет выхода (Нет Конструкторы не был вызван)

B b(A()); 
b.a.p(); // error here 

Got компилировать ошибка. Итак, в чем разница между этими двумя конструкторами?

+0

Вы не вызывали конструктора, хотя, возможно, вы и подумали. –

+0

Я думаю, вы должны сделать, как A a; B b (a); который работает нормально, как ожидалось. то, что вы упомянули, это функция decl, а не object decl. – chinnagaja

ответ

5
B b(A()); 

Это не объявляет объект. Он объявляет функцию, называемую b, с типом возврата B, который принимает указатель на функцию с возвращаемым типом A в качестве аргумента.

Что вы хотите:

B b = A(); 

или (спасибо Kerrek):

B b((A())); 

или в C++ 11:

B b {A()}; 

Это иногда называют vexing parse ,

+3

Просто 'B b ((A()));' будет делать. A [little lisp] (http://stackoverflow.com/a/8839746/596781) никому не повредит. –

+0

[Другая ссылка lisp] (http://stackoverflow.com/a/6298050/636019);] Кроме того, более последовательная версия C++ 11 будет 'B b {A {}};'. – ildjarn

+0

Известный как самый неприятный парсис: http://en.wikipedia.org/wiki/Most_vexing_parse –

Смежные вопросы