派生类的c ++向量只调用一次构造函数

时间:2011-09-04 00:40:56

标签: c++ inheritance stl vector constructor

如果我创建派生类的大小2 std::vector,则只调用一次构造函数。如果我创建一个基类的大小为2的向量,则构造函数被调用两次。

我通常不会发布复制问题的完整代码,但在这种情况下,它可以很短:

#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;
}

以上对我的输出是:

base constructor
----------------
base constructor
derived constructor

为什么输出不是以下内容:

base constructor
base constructor
----------------
derived constructor
derived constructor

我在Linux上使用gcc 4.5.2。

3 个答案:

答案 0 :(得分:6)

你在欺骗自己:派生对象的一个​​默认构造调用两个构造函数。

现在,您看到的是复制构造函数,实际上在两种情况下都会被调用两次。

您正在调用的vector构造函数使一个默认构造其值类型,然后复制到每个元素中:

//std::vector<Derived> v(2);

std::vector<Derived> v(2, Derived()); // same thing!

答案 1 :(得分:3)

这是Kerrek写的一些扩展:

#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;
}

这个输出是:

base constructor
copy base constructor
copy base constructor

base constructor
derived constructor
copy base constructor
copy derived constructor
copy base constructor
copy derived constructor

答案 2 :(得分:2)

这是我从VC ++ 2010获得的输出:

base constructor
base constructor
base constructor
derived constructor
base constructor
derived constructor
Press any key to continue . . .

而(GCC)4.6.1

g++ -o test test.cpp
sashan@cyclops cpp  $ ./test
base constructor
base constructor
derived constructor

所以它看起来像是一个实现差异....这有点令人费解。

更新

使用c ++ 0x进行编译得出:

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

支持Kerrek SB的评论和回答。