我们可以通过两种方式创建对象:
myClass myObject = myClass(123);
//or
myClass myObject(123);
这两者之间的背景有什么不同吗?我想使用第一个,但似乎要结合这两行:
myClass myObject;
myObject= myClass(123);
第二个也做同样的事吗?
答案 0 :(得分:10)
myClass myVariable = myClass(123);
myClass myVariable(123);
myClass myVariable;
myVariable = myClass(123);
是default initialization,后跟copy (or move) assignment。
通常,由于copy elision,前两个是相同的。相关规则可以在[class.copy] / 31(N4140,C ++ 14标准草案)中找到:
当满足某些条件时,允许省略实现 复制/移动类对象的构造[...]:
- 当一个尚未绑定到引用的临时类对象时 (12.2)将被复制/移动到具有相同的类对象 cv-unqualified类型,可以省略复制/移动操作 将临时对象直接构造到目标中 省略了复制/移动
答案 1 :(得分:1)
最后我不知道。您已经描述了三种定义对象的方法,并且所有3种方法都将对象放在堆栈顶部,调用相同的构造函数。如果您使用new
运算符,则功能会有所不同。
答案 2 :(得分:1)
这个不使用赋值运算符(据我所知,这两行是等价的)。语法中使用了=
,但实际上并未使用operator=
:
myClass myVariable = myClass(123);
//or
myClass myVariable(123);
这个使用赋值运算符:
myClass myVariable;
myVariable = myClass(123);
如果赋值运算符严重或未实现,则第一个语句有效,第二个可能(并且很可能)崩溃。
#include <iostream>
#include <string.h>
using namespace std;
class Dvector
{
public:
Dvector( int thesize = 0 )
{
std::cout << "Constructing object of size " << thesize << std::endl;
size = thesize;
data = new double[size];
}
Dvector( const Dvector& v )
{
std::cout << "Constructing object of size " << v.size << " by copy" << std::endl;
size = v.size;
data = new double[size];
memcpy( data, v.data, sizeof(double)*size );
}
Dvector& operator=( const Dvector& v )
{
std::cout << "Assigning object of size " << v.size << std::endl;
if ( &v != this )
{
size = v.size;
data = new double[size];
memcpy( data, v.data, sizeof(double)*size );
}
return *this;
}
~Dvector()
{
std::cout << "Destroying object" << std::endl;
delete [] data;
}
private:
double* data;
int size;
};
int main() {
Dvector v = Dvector(3);
return 0;
}
显示器:
Constructing object of size 3
Destroying object
当:
int main() {
Dvector v;
v = Dvector(3);
return 0;
}
显示器:
Constructing object of size 0
Constructing object of size 3
Assigning object of size 3
Destroying object
Destroying object
如果未定义复制构造函数,则会崩溃...因为v.data
最终指向由临时变量(data
)分配的Dvector(3)
,然后被删除。尝试访问v.data
或v
销毁(删除已释放的内存)时可能发生崩溃。