Reputation: 4521
I'm new to c++ programming language. I wrote several patterns of code to understand c++ constructor and initializer. But I couldn't find out why one build fail and another doesn't. From my view, there seems no such difference that one fail and another doesn't. The code is the following 5 codes. What's the difference between code example 1-2, 2-3, 3-4, 4-5. Why one fail but another doesn't?
Additional Info:
I'm building these code with Xcode 8.2.
The Code
Example 1:
class A{
public:
A(int xxx) { }
};
int main(){
A a; // Fail here. I see this is because there is no default constructor in definition of class A.
}
Example 2:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a; // No fail. Why? I supposed it will fail like Example 1.
};
int main(){
}
Example 3:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a; // No fail here.
B(int xxx) { } // But fail here. Why? I just added constructor to Example 2.
};
int main(){
}
Example 4:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a;
B(int xxx) : a(123) { } // No fail. Why Just adding ":a(123)" works.
};
int main(){
}
Example 5:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a;
B(int xxx){ a = 123; } // Fail again. Why? I think ":a(123)" and "a=123" is same meaning.
};
int main(){
}
Upvotes: 0
Views: 104
Reputation: 3305
B
o A
in your mainB
you don't call to A::A()
and A
has no default constructorA::A()
in your B
constructor.A::A()
and A
has no default constructor. But 123
can be asigned to A
(because the implicitly-declared copy assignment operator is declared, and you have a constructor to build an A
from an int
)Upvotes: 0
Reputation: 5136
You seem to be getting the hang of most of this, so let me go through them all and clarify.
Example 1: You're trying to create an instance of A without supplying the constructor arguments it needs.
Example 2: The class B
can't be instantiated since it needs to create an instance of A
and you haven't specified which arguments to send to its constructor. You would get a compiler error here if you were to create an instance of B
somewhere. For example by putting B b;
in main().
Example 3: The constructor B::B(int)
fails to compile because you haven't specified valid arguments to the constructor of B::a
(its instance of A
). You're getting the error here, since it's during this constructor you would have to specify the arguments to a``.
Example 4: Here you are specifying, in the initialization list of B::B
which arguments it should pass to B::a
. This is what you need to do in order for it to compile.
Example 5: Here you're trying to assign a the value of 123
. This is done in the body of the constructor B::B
, which is called after all members of B
have been initialized. It's not specifying the arguments to the constructor of a
. It's just trying to assign a new value to it after it has already been constructed. Since you're not specifying a value which should be sent to the constructor of a
, you get the same error as in Example 3.
Upvotes: 2
Reputation: 181068
There is no error for example 2 since you never try to construct a B
. If you add to main B b;
then you will get an error like
error: use of deleted function 'B::B()'
The reason you do not get an error before you try to instantiate a B
is because A a;
is just a member declaration. It is not until the constructor is called and you try to instantiate a
that you find out it is not default constructable.
Example 3 is basically the same thing. Now that you are defining a constructor the compiler will automatically add the default initialization of a
to it since you did not provide one in the member initializer list. When it does that it sees A
is not default constructable so it issues the error.
Example 4 does not fail because you specify how to construct a
. Since you did that the compiler will not try to default construct it and instead it constructs a
with the value you provided.
Example 5 fails again because of the same reason in example 3. It tries to add a default initialization to the member initialization list but can't since it does not exists, which give you the error.
Upvotes: 4