Alan Turing
Alan Turing

Reputation: 12581

c++ vector of derived class calls constructor only once

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

Answers (3)

sashang
sashang

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.

Update

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

Darcy Rayner
Darcy Rayner

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

Kerrek SB
Kerrek SB

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

Related Questions