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 &);
    //...
};

andの freindにArray::operator=andのfreindと同じことをさせたいのですが、, の代わりに,を返す必要があります。私は何十ものメソッドでそれを行う必要があるので、以下よりも簡単に実装する方法はありますか?Arrayoperator+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

0

最終的に、私は答えを見つけることができました。の場合operator=:

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

書くだけArray &operator=(const DataStructure &);で hideDataStructure::operator=になりますが、usingステートメントではメソッドの戻り値の型が変わるだけです。

注:usingステートメントは行の前に置く必要があります。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 に答える