c ++ вектор производного класса вызывает конструктор только один раз - PullRequest
2 голосов
/ 04 сентября 2011

Если я сделаю размер 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

Я использую gcc 4.5.2 в Linux.

Ответы [ 3 ]

6 голосов
/ 04 сентября 2011

Вы обманываете себя: одна конструкция по умолчанию для производного объекта вызывает оба конструктора.

Теперь, то, что вы не , видите скопировать конструктор , который в обоих случаях вызывается дважды.

Конструктор vector, который вы вызываете, создает одну конструкцию по умолчанию своего типа значения,а затем копирует это в каждый элемент:

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

std::vector<Derived> v(2, Derived()); // same thing!
3 голосов
/ 04 сентября 2011

Это немного расширение того, что написал Керек:

#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 голосов
/ 04 сентября 2011

Это вывод, полученный от 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.

...