C++ 中 operator= 的继承问题 [英] Trouble with inheritance of operator= in C++

查看:25
本文介绍了C++ 中 operator= 的继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在继承 operator= 时遇到问题.为什么此代码不起作用,修复它的最佳方法是什么?

I'm having trouble with the inheritance of operator=. Why doesn't this code work, and what is the best way to fix it?

#include <iostream>

class A
{
public:
    A & operator=(const A & a)
    {
        x = a.x;
        return *this;
    }

    bool operator==(const A & a)
    {
        return x == a.x;
    }

    virtual int get() = 0; // Abstract

protected:
    int x;
};

class B : public A
{
public:
    B(int x)
    {
        this->x = x;
    }

    int get()
    {
        return x;
    }
};

class C : public A
{
public:
    C(int x)
    {
        this->x = x;
    }

    int get()
    {
        return x;
    }
};

int main()
{
    B b(3);
    C c(7);
    printf("B: %d C: %d B==C: %d
", b.get(), c.get(), b==c);

    b = c; // compile error
    // error: no match for 'operator= in 'b = c'
    // note: candidates are B& B::operator=(const B&)

    printf("B: %d C: %d B==C: %d
", b.get(), c.get(), b==c);
    return 0;
}

推荐答案

如果你没有在类中声明复制赋值运算符,编译器会为你隐式声明一个.隐式声明的复制赋值运算符将隐藏任何继承的赋值运算符(阅读 C++ 中的名称隐藏"),这意味着任何继承的赋值运算符将对 未限定变得不可见"em> 名称查找过程(当您执行 b = c 时会发生这种情况),除非您采取特定步骤取消隐藏"它们.

If you do not declare copy-assignment operator in a class, the compiler will declare one for you implicitly. The implicitly declared copy-assignment operator will hide any inherited assignment operators (read about "name hiding" in C++), meaning that any inherited assignment operators will become "invisible" to the unqualified name lookup process (which is what happens when you do b = c), unless you take specific steps to "unhide" them.

在您的情况下,B 类没有明确声明的复制赋值运算符.这意味着编译器会声明

In your case, class B has no explicitly declared copy-assignment operator. Which mean that the compiler will declare

B& B::operator =(const B&)

隐含的.它将隐藏从 A 继承的操作符.线

implicitly. It will hide the operator inherited from A. The line

b = c;

不编译,因为这里唯一的候选对象是上面隐式声明的 B::operator =(编译器已经告诉你了);所有其他候选人都是隐藏的.由于 c 不能转换为 B&,上面的赋值不能编译.

does not compile, because, the only candidate here is the above implicitly declared B::operator = (the compiler told you about that already); all other candidates are hidden. And since c is not convertible to B&, the above assignment does not compile.

如果你想让你的代码编译,你可以使用 using-declaration 通过添加

If you want your code to compile, you can use using-declaration to unhide the inherited A::operator = by adding

using A::operator =;

B类的定义.代码现在可以编译了,尽管它不是一个好的样式.你必须记住,在这种情况下,b = c 赋值将调用 A::operator =,它只分配 A 部分所涉及的对象.(但显然这是你的意图.)

to the definition of class B. The code will now compile, although it won't be a good style. You have to keep in mind that in this case the b = c assignment will invoke A::operator =, which assigns only the A portions of the objects involved. (But apparently that is your intent.)

或者,在这种情况下,您始终可以通过使用名称的 限定 版本来解决名称隐藏问题

Alternatively, in cases like this you can always work around name hiding by using a qualified version of the name

b.A::operator =(c);

这篇关于C++ 中 operator= 的继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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