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

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

问题描述

我只是尝试使用这段代码的参考:

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; / code>产生错误。相反,当我编译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:为什么会出现此警告?

参考 。您不能在创建后重新分配对另一个相同类型变量的引用,因为引用只是创建它的类型变量的别名,并将继续保留。尝试重新分配它会产生一个错误。

通常,编译器默认会为每个类生成一个隐式位分配操作符,但在这种情况下由于 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.

只是为了重复在您的代码示例中执行的操作:

Just to reiterate the operations being performed in your code example:

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&)声明显式,并且不能通过作为转换函数 c>的隐式转换

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天全站免登陆