Reputation: 10156
Why does the following not work when chaining constructors:
#include <iostream>
#include <vector>
class cls {
public:
cls() {cls(5);} // want to resize v to 5
cls(int n) {v.resize(n);}
std::vector<int> v;
};
int main(int argc, const char* argv[]) {
cls x, y(5);
std::cout << x.v.size() << std::endl; // prints 0 <- expected 5
std::cout << y.v.size(); // prints 5
return 0;
}
Demo: http://ideone.com/30UBzS
I expected both objects to have a v
of size 5. What's wrong?
Reason I want to do this is because writing separate cls()
and cls(n)
ctors would duplicate a lot of code.
Upvotes: 1
Views: 70
Reputation: 693
Here is what you need:
class cls
{
public:
cls()
:
v( 5 ){} // create v that contains 5 elements ( each initialized to 0 ) - note: this is NOT resizing
explicit cls( const int size )
:
v( size ){}
private:
std::vector<int> v;
};
Of course, if you need resizing feature on the living object, you will need a 'resize' method already mentioned in this thread.
Upvotes: 0
Reputation: 3560
Calling cls(5);
inside of the cls::cls()
constructor is not doing what you think it is doing. It is creating a temporary variable using the second cls
constructor which is destroyed at ;
.
You can use C++11's delegating constructors to achieve what you want:
cls() : cls(5) { }
If you don't have a compiler that supports C++11, you can pull the common initialisation out into another function, and have both constructors call that:
class cls {
public:
cls() { init(5); }
cls(int n) { init(n); }
std::vector<int> v;
private:
void init(int n) { v.resize(n); }
};
Upvotes: 2
Reputation: 5988
You should change
cls() {cls(5);}
to
cls() {v.resize(5);}
Otherwise you are creating new temporary cls
in the constructor and ignoring it.
OR If you want to delegate the constructor
(C++11) do it like this
cls() : cls(5) {}
// ^^ ^
// | use cls(int n)
delegated constructor are allowed only in the member initialization
list of a constructor.
Upvotes: 0
Reputation: 96810
cal(5)
creates a completely different object, in fact it's a temporary meaning the object will be destroyed at the end of its encapsulation expression. Or it might not be called at all due to compiler optimization.
But with that aside, the constructor call only affects the temporary and not the original object calling the constructor.
If your intention was to make the code shorter, you should create a member function that does this (assuming your compiler doesn't support C++11, in which case you could simply use the Delegating Constructor feature):
class cls
{
void resize(int n)
{
v.resize(n);
}
public:
cls() { resize(5); }
cls(int n) { resize(n); }
std::vector<int> v;
};
Upvotes: 0