语言:C ++
我的问题是在以下情况下是否调用复制构造函数或赋值运算符。在此之前,我了解以下内容:
MyClass a(3); // single param constructor
MyClass b(a); // copy constructor invoked
MyClass c = b; // copy constructor invoked
MyClass d; // default constructor
d = c; // assignment operator invoked
但是,我希望有人能对此提供类似的细分:
1)对于第2-3行,是调用赋值运算符还是复制构造函数?
MyClass arr[10];
arr[2] = a;
arr[5] = MyClass(1);
2)构造函数,然后复制构造函数?还是构造函数,然后是赋值运算符?
MyClass arr2[] = {MyClass(), MyClass(9)};
3)假设向量v
的内部表示空间还有一个对象,是使用赋值运算符还是复制构造函数复制新元素?
std::vector<MyClass> v;
v.push_back(MyClass(2));
...
...
4)假设向量v
的内部表示空间不足并且必须重新分配,是使用赋值运算符复制旧元素还是复制构造函数?
v.push_back(MyClass(2)); // Assuming vector is out of space; must realloc
答案 0 :(得分:1)
有空
type variable_name = some_value
然后,您将声明一个变量,并且将始终调用其构造函数(如果有)。这称为复制初始化,并且永远不会赋值
所以,在
MyClass arr[10]; // 1
arr[2] = a; // 2
arr[5] = MyClass(1); // 3
第1行创建一个包含10个MyClass
的数组,并默认构造每个数组。第2行和第3行是分配。
在
MyClass arr2[] = {MyClass(), MyClass(9)};
您可以使用* braced-init-list`中的值作为数组成员的初始化程序来初始化2个对象的数组。控制list initialization的规则很多,但它们的共同点是不会发生分配,只会进行构造函数调用。
使用
std::vector<MyClass> v;
v.push_back(MyClass(2));
假设向量没有重新分配,您有一个MyClass(2)
的构造函数调用,然后向量中的元素是从该临时对象复制构造的。如果必须增加向量,则将所有当前元素复制/移动到新缓冲区中,然后在最后复制临时元素。
答案 1 :(得分:1)
MyClass arr[10];
MyClass的构造函数被调用10次,因为创建了10个arr对象。
arr[2] = a;
调用赋值运算符,将arr[2]
分配给a
。
arr[5] = MyClass(1);
第一个带有参数1
的单个param构造函数被调用并创建MyClass对象。然后调用赋值运算符。
MyClass arr2[] = {MyClass(), MyClass(9)};
这里仅调用了两个构造函数。首先是Myclass()
,然后是“单个参数构造函数” MyClass(9)
。具有初始化的数组声明不是分配,因为不存在要分配给它的现有数组成员。
std::vector<MyClass> v;
std::vector<MyClass>
的构造函数被调用。
v.push_back(MyClass(2));
std::vector::push_back
创建该类的副本并将其存储。因此,首先调用MyClass(2)
构造函数,然后调用复制构造函数MyClass(const MyClass &)
复制值。然后将复制的对象存储起来。
假设向量v的内部表示空间不足并且必须重新分配,是使用赋值运算符复制旧元素还是复制构造函数?
为每个成员调用复制运算符。所以:
std::vector<MyClass> a;
调用std::vector<MyClass>
的构造函数
a.push_back(MyClass(1));
调用MyClass(1)
的构造函数,并使用复制余量MyClass(MyClass&)
复制它。
之后,如果我们向数组添加另一个元素:
a.push_back(MyClass(2));
然后调用MyClass(2)
构造函数,然后为刚刚构造的MyClass(MyClass&)
对象的MyClass(2)
调用复制构造函数。然后,向量会复制ned的所有现有成员,因此对于向量MyClass(1)
中预先存在的对象,将调用已升级的复制构造函数。
真的,玩一点吧。并在所有位置插入cout以查看它:
struct MyClass {
MyClass(int a = 0) : _a(a) {
_count = count++;
std::cout << __func__ << " "
<< _count << " "
<< this << " "
<< this->_a << "\n";
}
MyClass(const MyClass &old_obj) {
this->_a = old_obj._a;
std::cout << __func__ << "Copy "
<< _count << " "
<< this << " "
<< this->_a << " "
<< &old_obj << " "
<< old_obj._a << "\n";
}
void operator=(const MyClass &old_obj) {
this->_a = old_obj._a;
std::cout << "MyClass" << __func__ << " "
<< _count << " "
<< this << " "
<< this->_a << " "
<< &old_obj << " "
<< old_obj._a << "\n";
}
static int count;
int _count;
int _a;
};
int MyClass::count = 0;