Reputation: 12581
If I make a size 2 std::vector
of a derived class, the constructor is called only once. If I make a size 2 vector of a base class, the constructor is called twice.
I usually wouldn't post the complete code that duplicates an issue, but in this case it can be made quite short:
#include <iostream>
#include <vector>
class Base {
public:
Base() { std::cout << "base constructor" << std::endl; }
virtual ~Base() {}
};
class Derived : public Base {
public:
Derived() { std::cout << "derived constructor" << std::endl; }
};
int main() {
std::vector<Base> base(2);
std::cout << "----------------" << std::endl;
std::vector<Derived> derived(2);
return 0;
}
The output of the above for me is:
base constructor
----------------
base constructor
derived constructor
Why is the output not the following:
base constructor
base constructor
----------------
derived constructor
derived constructor
I'm using gcc 4.5.2 on Linux.
Upvotes: 2
Views: 807
Reputation: 12214
This is the output I get from VC++ 2010:
base constructor
base constructor
base constructor
derived constructor
base constructor
derived constructor
Press any key to continue . . .
Whereas with (GCC) 4.6.1
g++ -o test test.cpp
sashan@cyclops cpp $ ./test
base constructor
base constructor
derived constructor
So it looks like it's an implementation difference....which is kinda puzzling.
Compiling with c++0x gives:
sashan@cyclops cpp 1 $ g++ -std=c++0x -o test test.cpp
sashan@cyclops cpp $ ./test
base constructor
base constructor
base constructor
derived constructor
base constructor
derived constructor
Which supports Kerrek SB's comments and answer.
Upvotes: 2
Reputation: 3445
This is a bit of an extension on what Kerrek wrote:
#include <iostream>
#include <vector>
class Base {
public:
Base() { std::cout << "base constructor" << std::endl; }
virtual ~Base() {
}
Base(const Base&){
std::cout << "copy base constructor" << std::endl;
}
};
class Derived : public Base {
public:
Derived() { std::cout << "derived constructor" << std::endl; }
Derived(const Derived& d):Base((const Base) d){
std::cout << "copy derived constructor" << std::endl;
}
};
int main() {
std::vector<Base> base(2);
std::cout << std::endl;
std::vector<Derived> derived(2);
return 0;
}
The output from this is:
base constructor
copy base constructor
copy base constructor
base constructor
derived constructor
copy base constructor
copy derived constructor
copy base constructor
copy derived constructor
Upvotes: 3
Reputation: 477358
You're deceiving yourself: A single default construction of the derived object calls both constructors.
Now, what you are not seeing is the copy constructor, which does in fact get called twice in both cases.
The constructor of vector
that you're calling makes one default construction of its value type, and then copies that into each element:
//std::vector<Derived> v(2);
std::vector<Derived> v(2, Derived()); // same thing!
Upvotes: 6