1

假设我们有 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=and的 freind 和and的Arrayfreindoperator+做同样的事情,除了他们应该返回,而不是, 。我需要用几十种方法来做,那么有没有比下面更简单的方法来实现它?DataStructure::operator=DataStructureoperator+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;
}

谢谢!

4

2 回答 2

1

Your implementation is not good : the operator= should return reference to object of type Array, and should not be virtual :

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

You can change DataStructure to use 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);
}

Check live demo. Then you have to implement the method add in your derived class Array.


To your edit :

Your new idea is an awful way of doing things in c++. What you do there is tell your compiler : "stop complaining, I know what I am doing". Also, it causing an undefined behaviour. It may appear to work, until you application starts crashing one day.

于 2013-06-10T17:13:50.750 回答
0

最终我设法找到了答案。对于operator=

class Array : public DataStructure {
public:
    //...
    using DataStructure::operator=;
    Array &operator=(const DataStructure &);
};

只写Array &operator=(const DataStructure &);会 hide DataStructure::operator=,但使用using语句它只会更改方法的返回类型。

注意:using语句必须在 line 之前,Array &operator=(const DataStructure &);否则operator=会模棱两可。


至于operator+,我发现的唯一解决方案是非常有问题的。它使用模板:

public DataStructure {
public:
    template<class T> friend const T &operator+(int, const T &);
};

例如,如果最初的实现是

const DataStructure &operator+(int x, const DataStructure &other) {
    DataStructure addition(other); /* in this example we assume
    *   that "DataStructure" isn't abstract */
    addition.someParameter += x; /* for simplicity, assume that
    *   "someParameter" is public/protected */
    return addition;
}

我们希望达到与

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

比我们可以简单地写:

template<class T>
const T &operator+(int x, const T &other) {
    DataStructure addition(other); /* notice that usually we would want
    *   to write "T" instead of "DataStructure", but sometimes it would
    *   give a different result */
    addition.someParameter += x;
    return (const T &)addition;
}

但是,如果存在一个operator+(int,/*const*/ ThirdClass /*&*/)与此无关的函数,DataStructure或者Array我们将不得不更改它,这可能会弄乱代码。幸运的是,通常只有几个友元函数,因此实现一个执行转换的新方法(如问题所示)并不是那么糟糕。

于 2013-06-10T21:41:06.677 回答