我定义了一个名为String的类,并使用=赋值来声明String对象来初始化它,但是我对后面的进程有一些疑问。让我们看看代码:
class String{
public:
String() :str(""){ cout << "default constructor" << endl; }
String(int n);
String(const char *p);
String(const String &x) :str(x.str)
{
cout << "copy constructor" << endl;
}
String& operator=(const String &x)
{
str = x.str;
cout << "operator =" << endl;
return *this;
}
string getStr() const
{
return str;
}
private:
string str;
};
ostream& operator<<(ostream &o,const String &x)
{
o << x.getStr();
return o;
}
String::String(int n)
{
stringstream ss;
ss << n;
ss >> str;
ss.clear();
ss.str("");
cout << "String(int n)" << endl;
}
String::String(const char *p)
{
str = *p;
}
int _tmain(int argc, _TCHAR* argv[])
{
String s6;
s6 = 10;
cout << s6 << endl;
return 0;
}结果如下:

这是可以理解的,首先调用默认构造函数,然后调用String::String(int n)构造函数,最后调用复制赋值。然后,我修改主要功能如下:
int _tmain(int argc, _TCHAR* argv[])
{
String s6=10;
cout << s6 << endl;
return 0;
}结果如下:

我不明白为什么它不叫复制分配,在这种情况下,它背后的过程是什么?
发布于 2017-05-10 07:34:09
你把任务和初始化搞混了。
String s6=10;不是赋值,而是初始化;更准确地说,是复制不对称。
1)当非引用类型
T的命名变量(自动、静态或线程局部)被声明时,初始化器由一个等号组成,后面跟着一个表达式。
因此,s6是由适当的构造函数(即String::String(int) )构造的,这里没有赋值。
发布于 2017-05-10 07:52:57
这不是作业,这是复制初始化。
T object = other;(1) ..。 如果Tother是类类型,而cv-不合格版本的T类型不是T或派生自E 221T,,或者如果T是非类类型,但other的类型是类类型,用户定义的转换序列可以从其他类型转换为T(或者如果T是类类型并提供转换函数,则转换为从T派生的类型),并通过过载解析选择最佳的转换序列。转换的结果,它是prvalue临时(直到C++17) prvalue表达式(自C++17),如果使用了转换构造函数,则使用来直接初始化对象.。
在您的情况下,T object = other转换为T object(T(other)) (直接初始化)。但
最后一步通常是优化出来的,转换的结果直接在分配给目标对象的内存中构造,但是即使不使用适当的构造函数(移动或复制),也需要访问它。(直到C++17)
最后选择的单词解释了为什么在直接初始化期间没有调用复制构造函数。
https://stackoverflow.com/questions/43886117
复制相似问题