gpt4 book ai didi

c++ - 存在引用时的赋值运算符和复制构造函数

转载 作者:可可西里 更新时间:2023-11-01 15:47:56 26 4
gpt4 key购买 nike

我只是用这段代码试验引用:

class A
{
};

class B
{
public:
B(A& a): m_a(a){}

A& m_a;
};

int main()
{
A a;
B b(a);
B b1 = b;
}

我原以为 B b1 = b; 都会产生错误。相反,当我用 VS2008 编译时,我只是收到警告

warning C4512: 'B' : assignment operator could not be generated

我明白为什么我会收到此警告。但是编译器不应该为 B b1 = b; 语句生成错误吗?这就像它生成了复制构造函数但没有生成赋值运算符。这两者不是彼此内在地联系在一起吗?当无法生成另一个时,只为其中一个生成默认实现是否有意义?

最佳答案

warning C4512: 'B' : assignment operator could not be generated

问题 1:为什么会出现此警告?
References 只能在创建时初始化一次。您不能在创建后将引用重新分配给另一个相同类型的变量,因为 Reference 只是为其创建它的类型变量的别名,并将继续如此。尝试重新分配它会产生错误。
通常,编译器默认为每个类生成一个隐式位赋值运算符,但在这种情况下,由于 class B 有一个引用作为成员 m_a,如果编译器要生成一个隐式赋值运算符,它会破坏不能重新分配引用的基本规则。因此编译器生成此警告以通知您它无法生成隐式赋值运算符。

问题 2:但是编译器不应该为 B b1 = b; 生成错误吗?也声明?
生成的警告和这个特定的操作没有任何关系。
B b1 = b; 调用隐式(正如@AndreyT 正确指出的那样)复制构造函数 B::B(const B&)。隐式拷贝构造函数是类默认生成的成员函数之一。所以它没有警告或错误。

问题三:好像生成了拷贝构造函数,但没有生成赋值运算符。这两者不是相互关联的吗?
不,他们根本没有关系。是的,编译器生成了一个复制构造函数,但由于上面问题 1 的回答中指定的原因,它无法生成赋值运算符。这是因为成员引用 m_a 可以在构造函数本身的主体中初始化。它只是创建时的初始赋值,而不是 = 中的赋值。

问题 4:当无法生成另一个时,只为其中一个生成默认实现是否有意义?
第 3 个问题的答案似乎可以回答这个问题。

只是重申您的代码示例中正在执行的操作:

B b(a); 调用转换复制构造函数 B::B(A&)
B b1 = b; 调用默认复制构造函数 B::B(const B&)

考虑其他场景。
如果您有 B b1 = a;,它将调用 B::B(A&),因此不会再出现错误。

但是如果 B::B(A&) 被声明为 explicit 并且不允许任何隐式转换,编译器会标记错误通过充当转换函数

勾选相同的here .

关于c++ - 存在引用时的赋值运算符和复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6120228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com