c++:继承具有不同(但协变)返回类型的方法

标签 c++ inheritance covariance return-type

假设我们有 2 个类:

class DataStructure {
public:
    DataStructure &operator=(const DataStructure &);
    friend const DataStructure &operator+(int, const DataStructure &);
    //...
};

class Array : public DataStructure {
public:
    Array &operator=(const DataStructure &);
    friend const Array &operator+(int, const Array &);
    //...
};

我们希望 Array::operator=Array 的 friend operator+ 做与 DataStructure::相同的事情: operator=DataStructure 的 friend operator+,除了它们应该返回 Array &,const Array & 而不是 DataStructure &const DataStructure &。我需要用几十种方法来实现,那么有没有比下面更简单的实现方式呢?

Array &Array::operator=(const DataStructure &other) {
    return (Array &)DataStructure::operator=(other);
}

const Array &operator+(int x, const Array &other) {
    return (const Array &)(x + (DataStructure)other);
}

编辑:我想到了另一个想法,尽管它很糟糕:

class Array;

class DataStructure {
public:
    //...
    operator Array &() const;
};
//...
DataStructure::operator Array &() const {
    return (Array &)*this;
}

这种方式 DataStructure 会在需要时隐式转换为 Array,尽管它仍然无法正确处理 DataStructureArray 是合法的,但做不同的事情,如本例所示:

//in class DataStructure:
public:
friend ostream &operator<<(ostream &os,const DataStructure &)
    { os << "DataStructure" << endl; return os;}
//in class Array:
public:
friend ostream &operator<<(ostream &os,const Array &)
    { os << "Array" << endl; return os;}
//...
int main() {
    Array x;
    cout << 1 + x << endl;
    // output: "DataStructure" instead of "Array"

    return 0;
}

谢谢!

最佳答案

您的实现不好:operator= 应该返回对数组类型对象的引用,并且不应该是虚拟的:

Array &Array::operator=(const DataStructure &other) {
    DataStructure::operator=(other);
    return *this;
}

您可以更改 DataStructure 以使用 NVI :

#include <iostream>

class DataStructure {
    public:
        DataStructure(){}
        inline virtual ~DataStructure(){}
        DataStructure &operator=(const DataStructure & other);
        inline friend const DataStructure &operator+(const int a, const DataStructure & other)
        { other.add(a); return other; }
        //...
    private:
        virtual void add( const int a ) const = 0;
    };
struct Array : DataStructure
{
    virtual void add( const int a ) const
    {
        std::cout<<"adding "<<a<<std::endl;
    }
};

void foo(const DataStructure &a)
{
    const DataStructure &b = 5 + a;
}

int main()
{
    Array a;
    foo(a);
}

检查 live demo .然后,您必须在派生类 Array 中实现方法 add


您的编辑:

你的新想法是用 C++ 做事的糟糕方式。你在那里做的是告诉你的编译器:“停止提示,我知道我在做什么”。此外,它会导致未定义的行为。它可能看起来有效,直到有一天您的应用程序开始崩溃。

关于c++:继承具有不同(但协变)返回类型的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17028885/

相关文章:

c++ - std::string 相关错误和处理它们,c++

inheritance - 如何在gradle任务之间共享代码?

covariance - 有人可以解释类型协方差/逆变和范畴论之间的联系吗?

java - 如何使协变 Consumer<?扩展基地>工作?

c++ - 如何在 C++ 中将文本文件读入二维动态 vector ?

c++ - 二叉存储树 fstream 出错

c++ - 鼠标移动时如何从WM_MOUSEMOVE中获取每个像素坐标?

c++ - 无法从派生类调用基模板类的构造函数

c++ - LuaBridge 和继承

c# - 为什么这是一个无效的方差?