0

Here are two classes

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"); }
};

Now following code works correctly

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

Prints:

A not empty constructor
A copy constructor
B constructor
in A

But if I use A constructor without parameters something strange happens

B b(A());

Compiles and run but no output (No constructors have been called)

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

Got compile error. So whats the difference between these two constructors?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Alexander
  • 779
  • 8
  • 17

1 Answers1

5
B b(A());

This does not declare an object. It declares a function called b, with return type B, that takes a pointer to a function with return type A as an argument.

What you want is:

B b = A();

or (thanks Kerrek):

B b((A()));

or in C++11:

B b {A()};

This is sometimes known as a vexing parse.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 3
    Simply `B b((A()));` will do. A [little lisp](http://stackoverflow.com/a/8839746/596781) has never hurt anyone. – Kerrek SB Jan 12 '12 at 20:01
  • [Another lisp reference](http://stackoverflow.com/a/6298050/636019) ;-] Also, a more consistent C++11 version would be `B b{A{}};`. – ildjarn Jan 12 '12 at 20:04
  • Thanks. Got it. B b = A(); wont work if B() is declared explicit. But B b((A())); works fine in both cases. – Alexander Jan 12 '12 at 20:08
  • 1
    The compile error should have made it clear that you declared `b` as a function, not a class instance. Mine (G++) gave: `request for member a in b, which is of non-class type B(A (*)())`. – David Schwartz Jan 12 '12 at 20:13