存在引用的赋值运算符和复制构造函数 [英] Assignment operator and copy constructor in the presence of references

查看:37
本文介绍了存在引用的赋值运算符和复制构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在尝试使用此代码的引用:

I am just experimenting with the references using this code:

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 进行编译时,我只会收到警告

I was expecting both B b1 = b; to produce a error. Instead when I compile with VS2008 I just get a warning

警告 C4512:'B':赋值无法生成运算符

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

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

I understand why I am getting this warning. But shouldn't the compiler generating an error for the B b1 = b; statement too? It is like it generated copy constructor but didn't generate assignment operator. Aren't these two inherently linked to one another ? does it makes sense to generate the default implementation for only one of them when the other could not be generated?

推荐答案

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

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

Question 1: Why this warning?
References can only be initialized once when they are created. You cannot reassign a reference to another same type variable after creation because Reference is just an alias of the type variable for which it was created and will continue to remain so. Attempting to reassign it generates an error.
Usually, a compiler generates an implicit bit wise assignment operator every class by default but in this case Since the class B has an reference as an member m_a, If the compiler were to generate an implicit assignment operator it would break the fundamental rule that references cannot be reassigned. So the compiler generates this warning to inform you that it could not generate the implicit assignment operator.

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

Question 2: But shouldn't the compiler generating an error for the B b1 = b; statement too?
The generated warning and this particular operation have no relation at all.
B b1 = b; invokes the implicit(as rightly pointed out by @AndreyT) copy constructor B::B(const B&). Implicit copy constructor is one of the member functions which a class generates by default. So there is no warning or error for it.

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

Question 3: It is like it generated copy constructor but didn't generate assignment operator. Aren't these two inherently linked to one another ?
No they are not related at all. Yes compiler generated a copy constructor but it could not generate a assignment operator for the reason specified in answer to Question 1 above. This is because the member reference m_a could be initialized in the body of the constructor itself. it's just the initial assignment at time of creation not assignment as in case of =.

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

Question 4: Does it makes sense to generate the default implementation for only one of them when the other could not be generated?
Answer to the 3 Question seems to answer this.

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

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

B b(a); invokes the conversion copy constructor B::B(A&)
B b1 = b; invokes the default copy constructor B::B(const B&)

考虑其他场景.
如果您有 B b1 = a; 它将调用 B::B(A&) 并且因此不会再次出错.

Consider the additional scenarios.
If you had B b1 = a; it would call B::B(A&) and hence no error again.

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

But compiler would mark a error if B::B(A&) was declared explicit and would not be allowed for any implicit conversions by acting as a conversion function.

此处检查相同的内容.

这篇关于存在引用的赋值运算符和复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆