3

一部の定数属性が異なる派生クラスがあります。すべての派生クラスで、属性を返す関数があります。get_x 関数を基本クラスに移動して重複を削除する方法はありますか? 私はこのスレッドと多くのグーグル検索を見てきましたが、私が望むものを正確に見つけることができませんでした: C++:派生クラスの異なる値で基本クラス定数静的変数を初期化していますか?

class Derived1: public Base{
    static const attribute x = SOME_ATTRIBUTE1;
    attribute get_x(){
        return x;
    }
};

class Derived2: public Base{
    static const attribute x = SOME_ATTRIBUTE2;
    attribute get_x(){
        return x;
    }
};

このように見えることを願っていますが、ベースで x が定義されていないため、これは機能しません。また、extern、静的 const 属性 x なども試しました。

class Derived1: public Base{
    static const attribute x = SOME_ATTRIBUTE1;
};

class Derived2: public Base{
    static const attribute x = SOME_ATTRIBUTE2;
};

class Base{
    attribute get_x(){
        return x;
    }
};

ありがとう。

4

3 に答える 3

2

少し厄介ですが、次のようなものを使用してこれを行うことができます。

template <attribute x> class Base
{
    public:
        attribute get_x ( ) { return x; }
};

class Derived1 : public Base<SOME_ATTRIBUTE_1>
{
    ...
};

class Derived2 : public Base<SOME_ATTRIBUTE_2>
{
    ...
};

カールの答えに似ていますが、継承された/派生した関係を保持します(まあ、ほとんど-以下の@visitorのコメントを参照してください)。

一方、単純なオーバーライドを行わない理由はありますか? 例えば:

class Base
{
    public:
        virtual attribute get_x ( ) = 0;
};

class Derived1 : public Base
{
    public:
        attribute get_x ( ) { return SOME_ATTRIBUTE_1; };
};

class Derived2 : public Base
{
    public:
        attribute get_x ( ) { return SOME_ATTRIBUTE_2; };
};

編集:テンプレート アプローチは、次のように、必要な数の属性に拡張できることに注意してください。

template <attribute1 x, attribute2 y ...> class Base
{
    public:
        attribute get_x ( ) { return x; }
        attribute get_y ( ) { return y; }
        ...
};

各属性をクラスのプロパティにする別のソリューションは、次のようになります。

class Base
{
    public:
        Base (attribute newX) : x(newX) { }
        attribute get_x ( ) { return x; };
    protected:
        const attribute x;
};

class Derived1 : public Base
{
    public:
        Derived1 ( ) : Base(SOME_ATTRIBUTE_1) { }
};

class Derived2 : public Base
{
    public:
        Derived2 ( ) : Base(SOME_ATTRIBUTE_2) { }
};

ここでは、それぞれDerivedがそのクラスに固有の定数プロパティを持っています。もちろん、必要に応じてドロップすることもできconstます。

于 2011-02-23T04:23:26.733 に答える
1

クラスの残りの部分がどのように見えるかにもよりますが、多態的な継承の代わりにテンプレートを使用するのが良いケースかもしれません:

template <attribute X>
class Base{
    attribute get_x(){
        return X;
    }
}

typedef Base<SOME_ATTRIBUTE1> Derived1;
typedef Base<SOME_ATTRIBUTE2> Derived2;
于 2011-02-23T04:21:46.620 に答える
1
#include <iostream>
#include <typeinfo>

enum attribute {SOME_ATTRIBUTE1, SOME_ATTRIBUTE2};

class Base
{
public:
    virtual attribute get_x() = 0;
};

template <attribute Attr>
class Derived : public Base
{
public:
    virtual attribute get_x() {return Attr;}
};

typedef Derived<SOME_ATTRIBUTE1> Derived1;
typedef Derived<SOME_ATTRIBUTE2> Derived2;

int main()
{
    std::cout << typeid(Derived1().get_x()).name() << '\n';
    return 0;
}
于 2011-02-23T15:48:34.587 に答える