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

查看:418
本文介绍了在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\n", 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\n", b.get(), c.get(), b==c);
    return 0;
}


推荐答案

- 在类中的赋值运算符,编译器将为您隐式声明一个。隐式声明的复制赋值操作符将隐藏任何继承的赋值操作符(读取C ++中的名称隐藏),意味着任何继承的赋值操作符对于不合格名称查找过程(这是当您执行 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天全站免登陆