创build一个类的实例

第1,2,3,4行有什么区别?

我什么时候使用每个?

为什么第3行打印constructor Foo和第7行返回一个错误,第8行不?

 #include <iostream> using namespace std; class Foo { public: Foo ( ) { cout << "constructor Foo\n"; } }; class Bar { public: Bar ( Foo ) { cout << "constructor Bar\n"; } }; int main() { /* 1 */ Foo* foo1 = new Foo (); /* 2 */ Foo* foo2 = new Foo; /* 3 */ Foo foo3; /* 4 */ Foo foo4 = Foo::Foo(); /* 5 */ Bar* bar1 = new Bar ( *new Foo() ); /* 6 */ Bar* bar2 = new Bar ( *new Foo ); /* 7 */ Bar* bar3 = new Bar ( Foo foo5 ); /* 8 */ Bar* bar3 = new Bar ( Foo::Foo() ); return 1; } 
  /* 1 */ Foo* foo1 = new Foo (); 

在dynamic内存中创build一个Footypes的对象。 foo1指向它。 通常情况下,你不会在C ++中使用原始指针,而是一个智能指针。 如果Foo是一个PODtypes,这将执行值初始化(这里不适用)。

  /* 2 */ Foo* foo2 = new Foo; 

与之前相同,因为Foo不是PODtypes。

  /* 3 */ Foo foo3; 

在自动存储器中创build一个名为foo3Foo对象。

  /* 4 */ Foo foo4 = Foo::Foo(); 

使用复制初始化在自动存储中创build名为foo4Foo对象。

  /* 5 */ Bar* bar1 = new Bar ( *new Foo() ); 

使用Bar的转换构造函数在dynamic存储中创buildBartypes的对象。 bar1是它的指针。

  /* 6 */ Bar* bar2 = new Bar ( *new Foo ); 

和之前一样。

  /* 7 */ Bar* bar3 = new Bar ( Foo foo5 ); 

这只是无效的语法。 你不能在那里声明一个variables。

  /* 8 */ Bar* bar3 = new Bar ( Foo::Foo() ); 

如果第bar3中没有声明bar3话, bar3按照同样的原则工作和工作到5和6。

5&6包含内存泄漏。

语法像new Bar ( Foo::Foo() ); 是不正常的。 这通常是new Bar ( (Foo()) ); 额外括号帐户最令人头痛的parsing。 (校正的)

  1. 从空闲存储中分配一些dynamic内存,并使用其默认构造函数在该内存中创build一个对象。 你永远不会删除它,所以内存泄漏。
  2. 与1完全相同; 在用户定义types的情况下,括号是可选的。
  3. 分配一些自动内存,并使用其默认构造函数在该内存中创build一个对象。 内存在对象超出范围时自动释放。
  4. 类似于3.从概念上讲,命名对象foo4是默认初始化 – 构造,复制和销毁临时对象; 通常情况下,这个结果与3相同。
  5. 分配一个dynamic对象,然后通过复制第一个来初始化第二个对象。 两个物体都被泄漏。 并且没有办法删除第一个,因为你不保留一个指针。
  6. 与5完全一样。
  7. 不编译。 Foo foo5是一个声明,而不是一个expression式; 函数(和构造函数)参数必须是expression式。
  8. 创build一个临时对象,并通过复制来初始化dynamic对象。 只有dynamic的对象被泄露; 在完整expression式的末尾临时被自动销毁。 请注意,您可以使用Foo()而不是等效的Foo::Foo() (或实际上Foo::Foo::Foo::Foo::Foo() )创build临时

我什么时候使用每个?

  1. 不要,除非你喜欢你的代码不必要的装饰。
  2. 当你想创build一个超过当前范围的对象。 请记住在完成后删除它,并学习如何使用智能指针更方便地控制生命周期。
  3. 当你想要一个只存在于当前范围内的对象时。
  4. 不要,除非你觉得3看起来很无聊,还有什么补充一些不必要的装饰。
  5. 不要,因为它泄漏的内存没有恢复的机会。
  6. 不要,因为它泄漏的内存没有恢复的机会。
  7. 不要,因为它不会编译
  8. 当你想从临时的Foo创build一个dynamic的Bar

行1,2,3,4将调用默认的构造函数。 它们在本质上是不同的,1,2是dynamic创build的对象,3,4是静态创build的对象。

在第7行中,您在参数调用中创build了一个对象。 所以它是一个错误。

第5行和第6行是内存泄漏的邀请。