C++ 创建类的实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12248703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating an instance of class
提问by Kolyunya
What's the difference between lines 1 , 2 , 3 , 4?
第 1 、 2 、 3 、 4 行之间有什么区别?
When do I use each?
我什么时候使用每个?
Why line 3 prints the constructor Foo
and line 7 returns an error and line 8 doesn't?
为什么第 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;
}
回答by Luchian Grigore
/* 1 */ Foo* foo1 = new Foo ();
Creates an object of type Foo
in dynamic memory. foo1
points to it. Normally, you wouldn't use raw pointers in C++, but rather a smart pointer. If Foo
was a POD-type, this would perform value-initialization (it doesn't apply here).
Foo
在动态内存中创建一个类型的对象。foo1
指向它。通常,您不会在 C++ 中使用原始指针,而是使用智能指针。如果Foo
是 POD 类型,这将执行值初始化(此处不适用)。
/* 2 */ Foo* foo2 = new Foo;
Identical to before, because Foo
is not a POD type.
与之前相同,因为Foo
不是 POD 类型。
/* 3 */ Foo foo3;
Creates a Foo
object called foo3
in automatic storage.
创建一个在自动存储中调用的Foo
对象foo3
。
/* 4 */ Foo foo4 = Foo::Foo();
Uses copy-initialization to create a Foo
object called foo4
in automatic storage.
使用复制初始化创建一个在自动存储中Foo
调用的对象foo4
。
/* 5 */ Bar* bar1 = new Bar ( *new Foo() );
Uses Bar
's conversion constructor to create an object of type Bar
in dynamic storage. bar1
is a pointer to it.
使用Bar
的转换构造函数Bar
在动态存储中创建类型对象。bar1
是一个指向它的指针。
/* 6 */ Bar* bar2 = new Bar ( *new Foo );
Same as before.
和之前一样。
/* 7 */ Bar* bar3 = new Bar ( Foo foo5 );
This is just invalid syntax. You can't declare a variable there.
这只是无效的语法。你不能在那里声明一个变量。
/* 8 */ Bar* bar3 = new Bar ( Foo::Foo() );
Would work and work by the same principle to 5 and 6 if bar3
wasn't declared on in 7.
如果bar3
没有在 7 中声明,将按照相同的原则工作和工作到 5 和 6 。
5 & 6contain memory leaks.
5 & 6包含内存泄漏。
Syntax like new Bar ( Foo::Foo() );
is not usual. It's usually new Bar ( (Foo()) );
- extra parenthesis account for most-vexing parse.(corrected)
语法 likenew Bar ( Foo::Foo() );
并不常见。通常是new Bar ( (Foo()) );
——额外的括号解释了最烦人的解析。(更正)
回答by Mike Seymour
- Allocates some dynamic memory from the free store, and creates an object in that memory using its default constructor. You never delete it, so the memory is leaked.
- Does exactly the same as 1; in the case of user-defined types, the parentheses are optional.
- Allocates some automatic memory, and creates an object in that memory using its default constructor. The memory is released automatically when the object goes out of scope.
- Similar to 3. Notionally, the named object
foo4
is initialised by default-constructing, copying and destroying a temporary object; usually, this is elided giving the same result as 3. - Allocates a dynamic object, then initialises a second by copying the first. Both objects are leaked; and there's no way to delete the first since you don't keep a pointer to it.
- Does exactly the same as 5.
- Does not compile.
Foo foo5
is a declaration, not an expression; function (and constructor) arguments must be expressions. - Creates a temporary object, and initialises a dynamic object by copying it. Only the dynamic object is leaked; the temporary is destroyed automatically at the end of the full expression. Note that you can create the temporary with just
Foo()
rather than the equivalentFoo::Foo()
(or indeedFoo::Foo::Foo::Foo::Foo()
)
- 从空闲存储分配一些动态内存,并使用其默认构造函数在该内存中创建一个对象。你永远不会删除它,所以内存泄漏。
- 与 1 完全相同;在用户定义类型的情况下,括号是可选的。
- 分配一些自动内存,并使用其默认构造函数在该内存中创建一个对象。当对象超出范围时,内存会自动释放。
- 类似于3。从概念上讲,命名对象
foo4
是通过默认构造、复制和销毁临时对象来初始化的;通常,这会被省略,结果与 3 相同。 - 分配一个动态对象,然后通过复制第一个对象来初始化第二个对象。两个对象都泄漏了;并且无法删除第一个,因为您没有保留指向它的指针。
- 和5完全一样。
- 不编译。
Foo foo5
是声明,而不是表达式;函数(和构造函数)参数必须是表达式。 - 创建一个临时对象,并通过复制它来初始化一个动态对象。只有动态对象被泄露;临时在完整表达式结束时自动销毁。请注意,您可以使用 just
Foo()
而不是等价物Foo::Foo()
(或实际上Foo::Foo::Foo::Foo::Foo()
)来创建临时
When do I use each?
我什么时候使用每个?
- Don't, unless you like unnecessary decorations on your code.
- When you want to create an object that outlives the current scope. Remember to delete it when you've finished with it, and learn how to use smart pointersto control the lifetime more conveniently.
- When you want an object that only exists in the current scope.
- Don't, unless you think 3 looks boring and what to add some unnecessary decoration.
- Don't, because it leaks memory with no chance of recovery.
- Don't, because it leaks memory with no chance of recovery.
- Don't, because it won't compile
- When you want to create a dynamic
Bar
from a temporaryFoo
.
- 不要,除非您喜欢代码中不必要的装饰。
- 当您想要创建一个比当前作用域更长的对象时。用完记得删除它,学习如何使用智能指针更方便地控制生命周期。
- 当您想要一个仅存在于当前作用域中的对象时。
- 不要,除非你觉得 3 看起来很无聊并且添加一些不必要的装饰。
- 不要,因为它会泄漏内存而没有恢复的机会。
- 不要,因为它会泄漏内存而没有恢复的机会。
- 不要,因为它不会编译
- 当您想
Bar
从临时Foo
.
回答by Coding Mash
Lines 1,2,3,4 will call the default constructor. They are different in the essence as 1,2 are dynamically created object and 3,4 are statically created objects.
第 1、2、3、4 行将调用默认构造函数。它们本质上是不同的,因为 1,2 是动态创建的对象,而 3,4 是静态创建的对象。
In Line 7, you create an object inside the argument call. So its an error.
在第 7 行,您在参数调用中创建了一个对象。所以它是一个错误。
And Lines 5 and 6 are invitation for memory leak.
第 5 行和第 6 行是内存泄漏的邀请。