ambiguous constructor call while object creation - c++

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).

Related

Why is this not considered as a default constructor?

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.

C++: explicit constructor is implicitly called by derived class

Why making a constructor explicit does not prevent it to be implicitly called by derived class?
class A{
public:
explicit A(){}
};
class B : public A{
public:
B(){ //Constructor A() is called implicitly
//...
}
}
I had a situation in my program when I'd rather have compiler error in that case, it would save me a lot of time to find a bug. For now I changed default constructor of A to accept a dummy "int" argument to achieve that, but shouldn't "explicit" keyword work for this?
g++-4.8 compiles the code above without any errors or warnings.
Your assumption is wrong on the explicit keyword.
The explicit keyword isn't meant to prevent the constructor from being called from a derived class but rather to prevent implicit conversions like the one in the sample here: https://stackoverflow.com/a/121163/1938163
I'm summarizing the relevant parts here:
class Foo
{
public:
// single parameter constructor, can be used as an implicit conversion
Foo (int foo) : m_foo (foo)
{
}
int GetFoo () { return m_foo; }
private:
int m_foo;
};
Since at most one implicit conversion can be done to resolve ambiguities, if you have a function like
void DoBar (Foo foo)
{
int i = foo.GetFoo();
}
the following is legit:
int main ()
{
DoBar (42); // Implicit conversion
}
And that's exactly where the explicit keyword comes into play: forbids the case above.
To solve your problem, in order to prevent your class from being used as a base class, just mark the constructor with final if you're using C++11 (http://en.wikipedia.org/wiki/C++11#Explicit_overrides_and_final)
explicit keyword is usually used with constructors that have one parameter. It prevents implicit construction of the object from type of the parameter to type of the class.
The example below will compile, and it usually is not what you want:
#include <iostream>
using namespace std;
struct Test
{
Test(int t) {}
};
void test_fun(Test t) {}
int main() {
test_fun(1); //implicit conversion
return 0;
}
With explicit keyword this example won't compile:
#include <iostream>
using namespace std;
struct Test
{
explicit Test(int t) {}
};
void test_fun(Test t) {}
int main() {
test_fun(1); //no implicit conversion, compiler error
return 0;
}

Benefit of Initialization List - Avoiding calls to default constructors

I was reading effective C++ and I couldn't really understand one of the mentioned benefit of initialization list.From what I understand is that initialization lists also help to avoid calling of unnecessary default constructors especially when they are not needed. So in order to test that I created a simple code example as such
class base
{
public:
base()
{
std::cout << "Default Constructor called \n";
}
base (int i)
{
std::cout << "Int constructor called \n";
}
};
class der : public base
{
private:
base b;
public:
der(int i):b(i)
{
std::cout << "Derived constructor called \n";
}
};
void main()
{
der d(12);
}
No where I assumed that only the int constructor will be called instead both the constructors of the base class are called. Could anyone please clarify this concept.
The problem is that you actually have 2 instances of base, one as a member and one as a base. Either change into der(int i):base(i),b(i) or remove the member.
Keep in mind that you are adding a member of type base to the der class, which also needs to be constructed. That member is being initialized with the constructor that doesn't take arguments. What you probably meant was:
class base
{
private:
int num;
public:
base()
{
std::cout << "Default Constructor called \n";
}
base (int i) : num(i)
{
std::cout << "Int constructor called \n";
}
};
class der : public base
{
private:
//base b;
public:
der(int i):base(i)
{
std::cout << "Derived constructor called \n";
}
};
void main()
{
der d(12);
}
der has two base instances, as explained by Ylisar. As base has default constructor, it will be implicitly called in der constructor.
Also C++ only supports below two forms of main function, there is no void main() in C++
§3.6.1 Main function
An implementation shall not predefine the main function. This function
shall not be overloaded. It shall have a return type of type int, but
otherwise its type is implementation-defined. All implementations
shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In your der,There are two base class, one is for inheriting, another one is b(the member of der).

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 I call a constructor from another constructor (do constructor chaining) in C++?

As a C# developer I'm used to running through constructors:
class Test {
public Test() {
DoSomething();
}
public Test(int count) : this() {
DoSomethingWithCount(count);
}
public Test(int count, string name) : this(count) {
DoSomethingWithName(name);
}
}
Is there a way to do this in C++?
I tried calling the Class name and using the 'this' keyword, but both fail.
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:
You can combine two (or more) constructors via default parameters:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};
Use an init method to share common code:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
// ...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
// ...
}
Foo::Foo(char x, int y)
{
init(x, y);
// ...
}
void Foo::init(char x, int y)
{
// ...
}
See the C++FAQ entry for reference.
Yes and No, depending on which version of C++.
In C++03, you can't call one constructor from another (called a delegating constructor).
This changed in C++11 (aka C++0x), which added support for the following syntax:
(example taken from Wikipedia)
class SomeType
{
int number;
public:
SomeType(int newNumber) : number(newNumber) {}
SomeType() : SomeType(42) {}
};
I believe you can call a constructor from a constructor. It will compile and run. I recently saw someone do this and it ran on both Windows and Linux.
It just doesn't do what you want. The inner constructor will construct a temporary local object which gets deleted once the outer constructor returns. They would have to be different constructors as well or you would create a recursive call.
Ref: https://isocpp.org/wiki/faq/ctors#init-methods
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
It is worth pointing out that you can call the constructor of a parent class in your constructor e.g.:
class A { /* ... */ };
class B : public A
{
B() : A()
{
// ...
}
};
But, no, you can't call another constructor of the same class upto C++03.
In C++11, a constructor can call another constructor overload:
class Foo {
int d;
public:
Foo (int i) : d(i) {}
Foo () : Foo(42) {} //New to C++11
};
Additionally, members can be initialized like this as well.
class Foo {
int d = 5;
public:
Foo (int i) : d(i) {}
};
This should eliminate the need to create the initialization helper method. And it is still recommended not calling any virtual functions in the constructors or destructors to avoid using any members that might not be initialized.
If you want to be evil, you can use the in-place "new" operator:
class Foo() {
Foo() { /* default constructor deliciousness */ }
Foo(Bar myParam) {
new (this) Foo();
/* bar your param all night long */
}
};
Seems to work for me.
edit
As #ElvedinHamzagic points out, if Foo contained an object which allocated memory, that object might not be freed. This complicates things further.
A more general example:
class Foo() {
private:
std::vector<int> Stuff;
public:
Foo()
: Stuff(42)
{
/* default constructor deliciousness */
}
Foo(Bar myParam)
{
this->~Foo();
new (this) Foo();
/* bar your param all night long */
}
};
Looks a bit less elegant, for sure. #JohnIdol's solution is much better.
Simply put, you cannot before C++11.
C++11 introduces delegating constructors:
Delegating constructor
If the name of the class itself appears as class-or-identifier in the
member initializer list, then the list must consist of that one member
initializer only; such constructor is known as the delegating
constructor, and the constructor selected by the only member of the
initializer list is the target constructor
In this case, the target constructor is selected by overload
resolution and executed first, then the control returns to the
delegating constructor and its body is executed.
Delegating constructors cannot be recursive.
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
};
Note that a delegating constructor is an all-or-nothing proposal; if a constructor delegates to another constructor, the calling constructor isn't allowed to have any other members in its initialization list. This makes sense if you think about initializing const/reference members once, and only once.
No, in C++ you cannot call a constructor from a constructor. What you can do, as warren pointed out, is:
Overload the constructor, using different signatures
Use default values on arguments, to make a "simpler" version available
Note that in the first case, you cannot reduce code duplication by calling one constructor from another. You can of course have a separate, private/protected, method that does all the initialization, and let the constructor mainly deal with argument handling.
Another option that has not been shown yet is to split your class into two, wrapping a lightweight interface class around your original class in order to achieve the effect you are looking for:
class Test_Base {
public Test_Base() {
DoSomething();
}
};
class Test : public Test_Base {
public Test() : Test_Base() {
}
public Test(int count) : Test_Base() {
DoSomethingWithCount(count);
}
};
This could get messy if you have many constructors that must call their "next level up" counterpart, but for a handful of constructors, it should be workable.
In Visual C++ you can also use this notation inside constructor: this->Classname::Classname(parameters of another constructor). See an example below:
class Vertex
{
private:
int x, y;
public:
Vertex(int xCoo, int yCoo): x(xCoo), y(yCoo) {}
Vertex()
{
this->Vertex::Vertex(-1, -1);
}
};
I don't know whether it works somewhere else, I only tested it in Visual C++ 2003 and 2008. You may also call several constructors this way, I suppose, just like in Java and C#.
P.S.: Frankly, I was surprised that this was not mentioned earlier.
This approach may work for some kinds of classes (when the assignment operator behaves 'well'):
Foo::Foo()
{
// do what every Foo is needing
...
}
Foo::Foo(char x)
{
*this = Foo();
// do the special things for a Foo with char
...
}
I would propose the use of a private friend method which implements the application logic of the constructor and is the called by the various constructors. Here is an example:
Assume we have a class called StreamArrayReader with some private fields:
private:
istream * in;
// More private fields
And we want to define the two constructors:
public:
StreamArrayReader(istream * in_stream);
StreamArrayReader(char * filepath);
// More constructors...
Where the second one simply makes use of the first one (and of course we don't want to duplicate the implementation of the former). Ideally, one would like to do something like:
StreamArrayReader::StreamArrayReader(istream * in_stream){
// Implementation
}
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
StreamArrayReader(&instream);
instream.close();
}
However, this is not allowed in C++. For that reason, we may define a private friend method as follows which implements what the first constructor is supposed to do:
private:
friend void init_stream_array_reader(StreamArrayReader *o, istream * is);
Now this method (because it's a friend) has access to the private fields of o. Then, the first constructor becomes:
StreamArrayReader::StreamArrayReader(istream * is) {
init_stream_array_reader(this, is);
}
Note that this does not create multiple copies for the newly created copies. The second one becomes:
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
init_stream_array_reader(this, &instream);
instream.close();
}
That is, instead of having one constructor calling another, both call a private friend!
If I understand your question correctly, you're asking if you can call multiple constructors in C++?
If that's what you're looking for, then no - that is not possible.
You certainly can have multiple constructors, each with unique argument signatures, and then call the one you want when you instantiate a new object.
You can even have one constructor with defaulted arguments on the end.
But you may not have multiple constructors, and then call each of them separately.
When calling a constructor it actually allocates memory, either from the stack or from the heap. So calling a constructor in another constructor creates a local copy. So we are modifying another object, not the one we are focusing on.
Would be more easy to test, than decide :)
Try this:
#include <iostream>
class A {
public:
A( int a) : m_a(a) {
std::cout << "A::Ctor" << std::endl;
}
~A() {
std::cout << "A::dtor" << std::endl;
}
public:
int m_a;
};
class B : public A {
public:
B( int a, int b) : m_b(b), A(a) {}
public:
int m_b;
};
int main() {
B b(9, 6);
std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;
return 0;
}
and compile it with 98 std:
g++ main.cpp -std=c++98 -o test_1
you will see:
A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor
so :)