C++中变量声明的区别
Posted
技术标签:
【中文标题】C++中变量声明的区别【英文标题】:Differences in variable declarations in C++ 【发布时间】:2010-04-16 11:05:48 【问题描述】:Class A
;
A a
、A* a
和 A* a = new A()
有什么区别。
【问题讨论】:
关闭为“不是一个真正的问题”。给定的代码不是 C++。 【参考方案1】:A a;
使用默认构造函数创建一个存在于堆栈中的 A 实例。
A *a;
只是一个指向 A 的 未初始化 指针。此时它实际上并不指向 A 对象,但可以。初始化的指针(在本例中设置为 NULL)如下所示:
A *a = 0;
这里的区别是空指针不指向任何对象,而未初始化的指针可能指向任何地方。初始化指针是一个很好的做法,以免您发现自己想知道为什么您的程序会崩溃或产生不正确的结果。
同样,您不希望尝试取消引用 NULL 指针或未初始化的指针。但是您可以测试 NULL 指针。测试未初始化的指针会产生不确定和错误的结果。它实际上可能是 != 0 但肯定不会指向您想要指向的任何地方。确保在测试它们之前初始化指针并在尝试取消引用它们之前测试它们。
A a = new A();
应该写成
A *a = new A();
并创建了一个在堆上分配的新 A 对象。 A 对象是使用 default 构造函数创建的。
如果没有为类显式编写默认构造函数,编译器将隐式创建一个,尽管我不相信标准没有为隐式实例化的对象指定数据成员的状态。有关隐式默认构造函数的讨论,请参阅 Martin York 对此SO question 的回复。
【讨论】:
值得注意的是A a
也调用了默认构造函数,如果你要提到堆分配版本的话。
另外值得注意的是A *a;
创建了一个未初始化的指针。你唯一能做的就是给它赋值(意思是,没有比较或其他用途)。可能值得添加第四个示例,A *a = 0
,在这种情况下,a
可以用于比较。
最后一条语句不正确。对象A()
是使用值初始化 创建的。它不使用A
的任何构造函数(在这种情况下)。表达式A()
仅在用户显式声明时才使用默认构造函数。否则,初始化继续进行而不使用构造函数。
@AndreyT - 同意 - 如果没有为类显式定义默认构造函数,编译器将完成隐式构造。我在这里所做的假设是有一个——尽管 OP 的类是空的——因为通常定义了一个。区分是一个很好的区分,我感谢您指出这一点。我会在答案中添加注释。
考虑:struct A ~A() int const a; ;
。然后new A()
完全有效(并将a
初始化为零)。但是,如果它使用A a;
或new A
中的默认构造函数,则格式错误(因为const
成员)。因此,是否使用默认构造函数有很大的不同。【参考方案2】:
A a
声明了一个名为 a
的 A
实例
A *a
声明了一个指向 A
类的指针
A *a = new A()
在堆上为a
分配空间并调用正确的构造函数(如果没有指定构造函数,则执行默认初始化)。
有关最后一个表单的更多信息,请参阅http://en.wikipedia.org/wiki/New_%28C%2B%2B%29
【讨论】:
虽然最后一个应该是A* a = ...
最后一个不只是在堆上为a
分配空间。它还初始化A
对象,并声明一个指向它的指针。
@Jalf,A a 怎么样,它在哪里分配内存。我可以看到当我们将 A a 放入时,构造函数被隐式调用。
@Sachin:无论在哪里声明。如果一个类包含以这种方式声明的成员,它会将类对象的大小增加到足以容纳额外的A
。如果在函数中声明,则放入调用堆栈。
@jalf,这是否意味着除非我使用 new,否则内存会分配在堆栈上而不是堆上。以上是关于C++中变量声明的区别的主要内容,如果未能解决你的问题,请参考以下文章