Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 浅复制是否调用成员对象';建设者?_C++ - Fatal编程技术网

C++ 浅复制是否调用成员对象';建设者?

C++ 浅复制是否调用成员对象';建设者?,c++,C++,假设我有这个代码: class A { public: int x; A(){} A(const A& a){} //copy constructor operator= (const A &a){...} }; class B { public: A a; B(){} }; int main() { B b; B c = b; //shallow copy B d; d = b; //shallow

假设我有这个代码:

class A {
public:
    int x;
    A(){}
    A(const A& a){} //copy constructor
    operator= (const A &a){...}
};
class B {
public:
    A a;
    B(){}
};
int main() {
    B b;
    B c = b; //shallow copy
    B d;
    d = b; //shallow assignment
}
浅层复制\赋值是否会调用成员A的复制构造函数\赋值运算符重载?
或者,浅层复制是执行成员对象的用户创建的复制构造函数和赋值运算符,还是也执行浅层复制运算符?

然后回答是“是”,将调用复制构造函数,但赋值运算符不会

将调用复制构造函数,因为调用了默认的复制构造函数,但未调用赋值运算符。默认的赋值运算符将调用默认的复制构造函数,默认的复制构造函数将调用基类的复制构造函数,但不调用默认的赋值运算符

原因很简单:没有调用默认赋值运算符,因为默认赋值运算符声明为“A&operator=(const A&A)”


以上是使用调用约定(“默认值”是成员函数调用约定)的情况。

如果答案是“是”,将调用复制构造函数,但不会调用赋值运算符

将调用复制构造函数,因为调用了默认的复制构造函数,但未调用赋值运算符。默认的赋值运算符将调用默认的复制构造函数,默认的复制构造函数将调用基类的复制构造函数,但不调用默认的赋值运算符

原因很简单:没有调用默认赋值运算符,因为默认赋值运算符声明为“A&operator=(const A&A)”

以上是使用调用约定(“默认值”是成员函数调用约定)的情况。

术语“浅层副本”用于描述在“浅层副本”之后,两个对象以某种方式在内部引用同一对象的副本。因此,操纵一个对象可能会在概念上操纵通过另一个对象可见的值

除非
A
中存储的
int
的值是对某个对象的引用,否则
A
B
中没有任何内容引用对象。因此,这些对象的隐式定义副本不是“浅”(或“深”)。该限定不适用于未引用其他对象的对象

隐式定义的复制构造函数/赋值将执行每个子对象的成员级复制。只要这些子对象具有复制构造函数/赋值运算符,它们就会被隐式定义的版本调用。

术语“浅层复制”用于描述在“浅层复制”之后,两个对象以某种方式在内部引用同一对象的复制。因此,操纵一个对象可能会在概念上操纵通过另一个对象可见的值

除非
A
中存储的
int
的值是对某个对象的引用,否则
A
B
中没有任何内容引用对象。因此,这些对象的隐式定义副本不是“浅”(或“深”)。该限定不适用于未引用其他对象的对象


隐式定义的复制构造函数/赋值将执行每个子对象的成员级复制。只要这些子对象有复制构造函数/赋值运算符,它们就会被隐式定义的版本调用。

这些副本没有“浅”的地方。这些副本没有“浅”的地方。这个答案的第二段对我来说没有任何意义。“默认的赋值运算符将调用默认的复制构造函数”赋值运算符不调用复制构造函数,因为没有要构造的内容。这两个对象都是在赋值之前构造的。类的默认编译器生成的赋值运算符只是从一个对象到另一个对象的逐个成员赋值。因此,它应该调用被复制的每个成员的赋值运算符。因此,在本例中,生成的
B::operator=
应该是这样的:
classb{public:aa;B(){}B&operator=(const B&B){A=B.A;return*this;}A::operator=
这个答案的第二段对我来说没有任何意义。“默认的赋值运算符将调用默认的复制构造函数”赋值运算符不调用复制构造函数,因为没有要构造的内容。这两个对象都是在赋值之前构造的。类的默认编译器生成的赋值运算符只是从一个对象到另一个对象的逐个成员赋值。因此,它应该调用被复制的每个成员的赋值运算符。因此,在本例中,生成的
B::operator=
应该是这样的:
classb{public:aa;B(){}B&operator=(const B&B){A=B.A;return*this;}因此调用
A::operator=