Why is this not considered as a default constructor? - c++

I'm confused between the default constructor.
I've 2 codes, code A and code B
In code A I don't understand why A(int news) is not considered as default constructor whereas code B ParentClass(int id) is consider as default constructor
Why does code A isn't able to compile but code B is able to compile.
code A
class A{
public:
int s;
A(int news){
s = news;
}
void print()
{
cout << s;
}
};
int main()
{
A a;
a.print();
}
code B
class ParentClass{
public:
int id;
ParentClass(int id){
this->id = id;
}
void print(){
cout << id <<endl;
}
};
class ChildClass:public ParentClass
{
public:
int id;
ChildClass(int id):ParentClass(1)
{
this->id = id;
}
};
int main()
{
ChildClass c(2);
c.print();
}

After the edit, question finally becomes clear. Rewording my answer.
Preface. In C++, a default constructor is a constructor which has no arguments, or has default values for all it's arguments. It is used to create an object when no additional information is provided. For example,
Default a;
Default* p = new A;
In the code above, default constructor of Default is called.
In the example A you are trying to call default constructor of A - because A a calls A's default constructor. Since such constructor doesn't exist, you have a compilation error. The only constructor you've got is a one taking integer argument, and you can use following code to call it:
A a(42);
In the second example, you are calling non-default (user-provided) constructor of ChildClass - becasue ChildClass c(1) calls a constructor of ChildClass accepting one integer argument - and you have just that. By the way, this ChildClass constructor calls ParentClass constructor, which takes exactly one integer argument.

Related

Why can't I use a class object as a parameter

I have this problem with getting class to pass as a parameter for another class constructor. Basically the code is like this:
class A
{
public:
int ID;
A(int getID)
{
ID = getID;
}
}
and I want to use that class A as a member of class B like this:
class B
{
public:
A someA;
A someB;
int number;
B(A ObjectA, A ObjectB, int getNumber)
{
someA = ObjectA;
someB = ObjectB;
number = getNumber;
}
};
The errors are basically saying that there is no matching function to call B::B(). I don't know whats wrong with it. I have done similar things with vectors of object, so I thought why cant this thing works. Any inputs/correction is appreciated, thank you!
Sidenotes: I have tried adding a default constructor for B as suggested in another thread, but it ended up saying invalid use of B::B.
Use the initialization list for your objects:
B(A ObjectA, A ObjectB, int getNumber)
:someA(std::move(ObjectA)), someB(std::move(ObjectB)), number(getNumber)
{
}
This will use the default move constructor from your class.
I used move here because you are passing your objects by value, so it makes sense to move them. If you passed them by const&, then don't move them and use the default copy constructor.
Still, this is about A default constructor, there is no problem with the B default constructor in the code you showed.
The error happens because you didn't tell B how to initialize its A attributes, so it's looking for the default A constructor.
In C++ the attribute initialization is made as show by Matthieu, and not in the constructor's body. You can add a default A constructor, but you have to think if it's the behavior you want for your code.
Compiling the code below doesn't show any error.
class A {
public:
int ID;
A() {}
A(int getID) {
ID = getID;
}
};
class B {
public:
A someA;
A someB;
int number;
B() {}
B(A ObjectA, A ObjectB, int getNumber) {
someA = ObjectA;
someB = ObjectB;
number = getNumber;
}
};

Class with no name, constructor, destructor

I've read about class with no name...
Got that
class
{
int i;
};
is not valied while
class
{
int i;
}A;
is valid.
But how to have a: 1) constructor and :2) destructor and: 3) how to pass as an argument???
If the class is unnamed then it can't have a custom constructor/destructor (although the compiler will generate the usual default ones for you). That means you can't pass an argument to it at construction. However, there's probably nothing stopping you from either (1) adding one or methods to the class to pass data to it after construction, or (2) giving the class a name in the first place.
The second thing is valid, but you cannot access the member i since it will be private. It is valid only because You have created an object A of that class type.
To have a constructor, I think you have to give the class a name. Use this:
class myclass
{
int i;
public:
myclass(int a) //This is the constructor
{
i = a;
}
~myclass() //This is the destructor
{
//Whatever you want to do on destroying the object
}
};
and instantiate that class as follows:
myclass A(10);
or similarly.
Note: This is just my interpretation, it can be done in many other ways.
You are doomed using the class locally and accessing it through the local object A, only.
You can use it in a template, though:
template <typename T>
inline void print(const T& a) {
std::cout << a.x << std::endl;
}
int main()
{
class {
public: int x;
} a;
a.x = 1;
print(a);
}

ambiguous constructor call while object creation

My program is as follows:
class xxx{
public: explicit xxx(int v){cout<<"explicit constructor called"<<endl;}
xxx(int v,int n=0){cout<<"default constructor called"<<endl;}
};
int main(int argc, char *argv[])
{
xxx x1(20); //should call the explicit constructor
xxx x2(10,20); //should call the constructor with two variables
return 0;
}
When I compile I get the error:- "call of overloaded âxxx(int)â is ambiguous"
I know that compiler finds both constructor signature equal since I made an argument by default '0'.
Is there any way that compiler can treat the signatures different and the program would compile successfully?
You just need one constructor
class xxx
{
public:
explicit xxx(int v, int n=0)
{
cout << "default constructor called" << endl;
}
};
Then you could initialize XXX objects:
xxx x1(20); //should call the explicit constructor
xxx x2(10,20); //should call the construct
You have 2 choices:
Remove one of the constructors:
class xxx
{
public:
explicit xxx(int v, int n = 0); // don't forget explicit here
};
Remove the default parameter:
class xxx
{
public:
explicit xxx(int v);
xxx(int v,int n);
};
Either way the code in main() will work. The choice is yours (and is mostly a matter of a subjective taste).

Constructor chaining in C++

My understanding of constructor chaining is that , when there are more than one constructors in a class (overloaded constructors) , if one of them tries to call another constructor,then
this process is called CONSTRUCTOR CHAINING , which is not supported in C++ .
Recently I came across this paragraph while reading online material.... It goes like this ...
You may find yourself in the situation where you want to write a member function to re-initialize a class back to default values. Because you probably already have a constructor that does this, you may be tempted to try to call the constructor from your member function. As mentioned, chaining constructor calls are illegal in C++. You could copy the code from the constructor in your function, which would work, but lead to duplicate code. The best solution in this case is to move the code from the constructor to your new function, and have the constructor call your function to do the work of initializing the data.
Does a member function calling the constructor also come under constructor chaining ??
Please throw some light on this topic in C++ .
C++11 allows constructor chaining (partially). This feature is called "delegating constructors". So in C++11 you can do the following
class Foo
{
public:
Foo(int a) : Foo() { _a = a; }
Foo(char* b) : Foo() { _b = b; }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
However, there is a severe limitation that a constructor that calls another constructor is not allowed to initialize any other members. So you cannot do the following with a delegating constructor:
class Foo
{
public:
Foo(int a) : Foo(), _a(a) { }
Foo(char* b) : Foo(), _b(b) { }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
MSVC++2013 gives compile error "C3511: a call to a delegating constructor shall be the only member-initializer" for the latter code example.
The paragraph basically says this:
class X
{
void Init(params) {/*common initing code here*/ }
X(params1) { Init(someParams); /*custom code*/ }
X(params2) { Init(someOtherParams); /*custom code*/ }
};
You cannot call a constructor from a member function either. It may seem to you that you've done it, but that's an illusion:
class X
{
public:
X(int i):i(i){}
void f()
{
X(3); //this just creates a temprorary - doesn't call the ctor on this instance
}
int i;
};
int main()
{
using std::cout;
X x(4);
cout << x.i << "\n"; //prints 4
x.f();
cout << x.i << "\n"; //prints 4 again
}
That's not what the text says. It's suggesting your constructor call a member function which is normal and legal. This is to avoid explicitly calling the ctor again and to avoid duplicating code between your ctor and reset function.
Foo::Foo() {
Init();
}
void Foo::Reset() {
Init();
}
void Foo::Init() {
// ... do stuff ...
}
I'm not sure if it (calling a constructor from a member function) will work or not, but it's a bad practice. moving the initialize code to a new function is the logic way.
Basically saying, Don't call the constructor unless you constructing...
when we call constructor from a member function, then it will temporary create a object of its type.
in case if we are calling in derived class function then all the parent constructors are also gets executed and destroyed using destructor once function goes out of scope.
its not a Good Practice to call the constructors in member functions since it creates objects of every class derived.

Can constructor call another constructor in c++?

class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
Can the first constructor call the second one?
Not before C++11.
Extract the common functionality into a separate function instead. I usually name this function construct().
The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.
A destructor, however, can be called without a problem.
Not before C++0x, no.
BUT, just out of academic interest I've come up with a really horrible way* to do it using a placement operator "new" (someone care to point out how portable this is?)
#include <new>
#include <iostream>
class A
{
public:
A(int i, int j)
: i_(i), j_(j) { }
A(int i)
{ new (this) A(i, 13); }
int i_,j_;
};
int
main() {
A a1(10,11), a2(10);
std::cout
<< a1.i_ << ", "
<< a1.j_ << std::endl
<< a2.i_ << ", "
<< a2.j_ << std::endl;
return 0;
}
*Hell no, I don't write this in the production code.
The answer is in fact "yes", but as others have suggested, it doesn't do what you want. You can of course use the constructor of a base class, either implicitly or explicitly:
struct B {
B() {}
B( int x ) {}
};
struct A : public B {
A() {} // calls B() implicitly
A( int a, int b ) : B( b ) {} // calls B(int) explicitly
};
Not directly. There are a few ways to work around this.
From the initializer list of your class' constructor, you can call a constructor on any base class, and on all member variables.
So you can usually refactor your class and split it into several smaller ones to solve the problem. The commonly executed code can be placed in a member object or perhaps a base class. Then each of the main class' constructors just have to decide which construcotr to use to initialize that member.
class B {
B() { }
B(int b) { DoSomething(); }
}
class A{
A(int a = 5) : b(a) { } // call B's constructor which does something
A() : b() {} // call B's constructor which does nothing
B b;
};
This is an old question; however,
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
could be
class A{
A(int a = 5){
*this = A();
DoSomething();
}
A(){...}
}
As pointed out by Pavel Radzivilovsky in his answer, since C++ 11, it is possible. It is the same syntax as for explicitely calling the parent's class constructor from a child class. This is useful when a class needs to have multiple constructors (say, a default constructor and a constructor with attribute initialization) but some operations have to be done in all cases. This allows to avoid code repetitions.
Here is an example:
class A
{
public:
A()
{
foo();
}
A(Attribute attribute) : A()
{
this->attribute = attribute;
}
//------ some other code --------
private:
Attribute attribute;
void foo()
{...}
//------ some other code -------
};
In this simple example, I assume that the function foo() needs to be called in all cases for the object to be correctly initialized. With this syntax, if the second constructor (with attribute initialization) is called, it will first perform the operations in the default constructor before executing the instructions in the attribute-initialization constructor.
It can also be done the other way around: the default constructor can call another constructor with default parameters.
Before C++ 11, it was necessary to duplicate the common instructions of all constructors or define methods that do the actual object initialization.