简体   繁体   English

将赋值运算符从基类引入派生对象(C++11 之前)

[英]Bring to derived object the assignment operator from base (prior to C++11)

I have a code similar to this:我有一个类似的代码:

template <typename T>
struct B
{
    B &operator =(const T &) { return *this; }
};

struct D : B<int> {};

int main()
{
    D d;
    d = 0;

    return 0;
}

Which fails:失败了:

error: no viable overloaded '='
   d = 0;
   ~ ^ ~
note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const D' for 1st argument
struct D : B<int> {};
       ^
note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'int' to 'D' for 1st argument
struct D : B<int> {};
       ^

The error is easy to spot and understand: D lacks of assignment operator with int , even if its base class have it.该错误很容易发现和理解: D缺少带有int的赋值运算符,即使它的基类有它。 From onwards we can solve this issue "lifting" to the derived object the assignment operator from the base object:开始,我们可以解决这个问题,将赋值运算符从基础对象“提升”到派生对象:

struct D : B<int> { using B::operator =; /* Easy fix! */ };

But I'm working on a project, so this fix isn't available.但是我正在开发一个项目,所以这个修复程序不可用。 How was this solved prior to C++11?在 C++11 之前这是如何解决的?

using declarations for inheriting base class methods already works in C++98. using声明继承基类方法已经在 C++98 中工作。

It's using declarations to inherit constructors that doesn't.using声明来继承没有的构造函数

template <typename T>
struct B {
    B(const T&) {}
    B &operator=(const T&) { return *this; }
};

struct D : B<int> {
    // using B<int>::B;           // error, constructors can't be inherited
    using B<int>::operator=;
};

and you then need to implement one that initializes the base class:然后您需要实现一个初始化基类的方法:

struct D : B<int> {
    D(int v) : B(v) {}          // this works
    using B<int>::operator=;    // and this too
};

But I'm working on a c++98 project, so this fix isn't available.但是我正在开发一个 c++98 项目,所以这个修复程序不可用。 How was this solved prior to C++11?在 C++11 之前这是如何解决的?

Define an operator= in D that calls B::operator= :D中定义一个operator=调用B::operator=

struct D : B<int> {
    D& operator=(const int &rhs) {
        B<int>::operator=(rhs);
        return *this;
    }
};

First things first, the program(with using declaration ) works with C++98.首先,该程序(带有using 声明)适用于 C++98。 Working Demo with C++98 .使用 C++98 的工作演示

That is, a using declaration for the assignment operator of the base class inside the derived class is allowed by C++98.也就是说,C++98 允许在派生类中对基类的赋值运算符使用 using 声明。 Here is the relevant text from the standard:以下是标准中的相关文本

If an assignment operator brought from a base class into a derived class scope has the signature of a copy-assignment operator for the derived class (12.8), the using-declaration does not by itself suppress the implicit declaration of the derived class copy-assignment operator;如果从基类引入派生类作用域的赋值运算符具有派生类的复制赋值运算符的签名(12.8),则使用声明本身不会抑制派生类复制赋值的隐式声明操作员; the copy-assignment operator from the base class is hidden or overridden by the implicitly-declared copy- assignment operator of the derived class, as described below.基类的复制赋值运算符被派生类的隐式声明的复制赋值运算符隐藏或覆盖,如下所述。

(emphasis mine) (强调我的)

Note again that the important thing is that the using declaration for the assignment operator of base class is allowed.再次注意,重要的是允许基类赋值运算符的 using 声明。

Now, you can define an assignment operator= for the derived class that explicitly uses the base class as shown below:现在,您可以为显式使用基类的派生类定义赋值operator= ,如下所示:

struct D : B<int> {
    D& operator=(const int& obj) {
        B<int>::operator=(obj); //use base class assignment operator
        return *this;
    }
    
};

You can add the required operator function to your derived class and call the corresponding base class operator from that:您可以将所需的运算符函数添加到派生类中,并从中调用相应的基类运算符:

template <typename T>
struct B {
    B& operator = (const T&) { return *this; }
};

struct D : B<int> {
    D& operator = (const int& rhs) {
        B<int>::operator = (rhs);
        return *this;
    }
};

int main()
{
    D d;
    d = 0;

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在C ++ 11中仍然需要“使用”指令来从基类中提出在派生类中重载的方法 - Why is the “using” directive still needed in C++11 to bring forward methods from the base class that are overloaded in the derived class 在C ++ 11中根据派生类`operator ==`定义基类`operator ==`? - Defining base class `operator==` in terms of derived class `operator==` in C++11? C ++ 11字符串赋值运算符 - C++11 string assignment operator C ++ 11移动构造函数和赋值运算符 - C++11 move constructor and assignment operator 如何优雅地检查模板类型是否派生自C ++ 11中的特定基类? - How to elegantly check if the template type is derived from the specific base class in C++11? C++11:如何访问派生 class 中的基本 class 成员? - C++11: How to access base class member in a derived class? 在C ++ 11中将基类运算符用于派生类 - Using base class operators for derived classes in C++11 C++11:赋值运算符是否会阻止类型被 POD 并因此被全局初始化? - C++11: Does an assignment operator prevent a type from being POD, and thus being global-initialized? =删除用户定义的成员函数,除了构造函数,赋值运算符c ++ 11 - =delete for user defined member functions apart from constructor, assignment operator c++11 C ++ 11中赋值运算符的副作用评估顺序 - Evaluation order of side effects for assignment operator in C++11
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM