C++ c++;派生类的向量只调用构造函数一次
如果我对派生类进行大小2C++ c++;派生类的向量只调用构造函数一次,c++,inheritance,stl,vector,constructor,C++,Inheritance,Stl,Vector,Constructor,如果我对派生类进行大小2std::vector,则只调用一次构造函数。如果我为一个基类创建一个大小为2的向量,那么构造函数将被调用两次 我通常不会发布复制问题的完整代码,但在这种情况下,它可以非常简短: #include <iostream> #include <vector> class Base { public: Base() { std::cout << "base constructor" << std::endl; }
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
derived constructor
我在Linux上使用GCC4.5.2。你在欺骗自己:派生对象的一个默认构造调用两个构造函数 现在,您没有看到的是复制构造函数,它实际上在这两种情况下都会被调用两次 您正在调用的
vector
的构造函数对其值类型进行一个默认构造,然后将其复制到每个元素中:
//std::vector<Derived> v(2);
std::vector<Derived> v(2, Derived()); // same thing!
//std::vector v(2);
向量v(2,派生());//同样的事情!
这是对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;
}
这是我从VC++2010获得的输出:
base constructor
base constructor
base constructor
derived constructor
base constructor
derived constructor
Press any key to continue . . .
鉴于(GCC)4.6.1
所以看起来这是一个实现上的差异……这有点令人费解
更新
使用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的评论和回答。我猜这只是在制作一个对象?完美的测试用例。干得好,谢谢你;永远不要为此道歉。回滚:我认为带破折号的版本更好,不是吗?对我来说,虚线出现在
基本构造函数
的第一次输出之后,并且在虚线出现之后(实际上)基本构造函数\nDrived构造函数
。这是因为创建Base
类型的对象需要调用Base
构造函数,创建Derived
类型的对象需要调用Base
和Derived
构造函数。是的,我添加了虚线,但没有运行代码。一旦我运行了代码,我就看到了@Kerek SB在回答中描述的推理错误。为什么复制构造函数用于派生类,而默认构造函数用于基类?@Lex:No,No,复制构造函数用于填充向量。将一个默认构造的对象作为原型,然后从中复制所有向量元素。只有Derived::Derived(const-Derived&)
用于复制。@Lex:它没有!!将测试用例分为两个程序,您将看到!是Derived()
的构造调用了一个基和一个派生构造函数。明白了。完美的因此,如果您需要一个特殊的默认构造函数,那么还应该编写一个复制构造函数和赋值运算符。具体地说,在我的实际代码中,我有一个std::shared_ptr
,需要在构造时进行分配,我没有编写复制构造函数和赋值运算符。@Lex:C++98库设计只有一个版本的构造函数,它填充给定数量的元素,它是通过从原型复制来实现的。这就是设计。C++11添加了在适当位置构造元素的其他版本。使用-std=c++0x
编译以查看差异。VC+2010不是c++98——它们有一些部分c++11支持,同时还有一些新的容器构造函数。。。这很可能就是这样的结果。如果使用-std=c++0x
编译,也可以在GCC中获得放置行为。然后你也会得到直接的结构,没有副本。(事实上,我从来没有想过这一点,谢谢!只要打开C++11,你就会获得更好的效率!)你的意思是将std::cout
放入Base
复制构造函数而不是它的析构函数吗?
base constructor
base constructor
base constructor
derived constructor
base constructor
derived constructor
Press any key to continue . . .
g++ -o test test.cpp
sashan@cyclops cpp $ ./test
base constructor
base constructor
derived constructor
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