質問

直しとかは出来ないんですかっていう仮想の静的加C++?

例えば:

class BaseClass {
    public:
        BaseClass(const string& name) : _name(name) {}
        string GetName() const { return _name; }
        virtual void UseClass() = 0;
    private:
        const string _name;
};


class DerivedClass : public BaseClass {
    public:
        DerivedClass() : BaseClass("DerivedClass") {}
        virtual void UseClass() { /* do something */ }
};

この例では自明でなければならないベクトルの複雑なデータは常に同じすべての派生クラスである必要があるからアクセスの基底クラス方法を教えてください。

class BaseClass {
    public:
        BaseClass() {}
        virtual string GetName() const = 0;
        virtual void UseClass() = 0;
};


class DerivedClass : public BaseClass {
    public:
        DerivedClass() {}
        virtual string GetName() const { return _name; }
        virtual void UseClass() { /* do something */ }
    private:
        static const string _name;
};

string DerivedClass::_name = "DerivedClass";

このソリューションなsatifyをわきまえていない私にはとて必要なメソッドを再実装しの参_nameよびそのアクセス用メソッドGetName()されるのではありません。私の場合は複数の会員が以下の_name動十分の由来。

ずっと面白いアイデアないか?

役に立ちましたか?

解決

こちらはoneソリューション:

struct BaseData
{
  const string my_word;
  const int my_number;
};

class Base
{
public:
    Base(const BaseData* apBaseData)
    {
        mpBaseData = apBaseData;
    }
    const string getMyWord()
    {
        return mpBaseData->my_word;
    }
    int getMyNumber()
    {
        return mpBaseData->my_number;
    }
private:
    const BaseData* mpBaseData;
};

class Derived : public Base
{
public:
    Derived() : Base(&sBaseData)
    {
    }
private:
    static BaseData sBaseData;
}

BaseData Derived::BaseData = { "Foo", 42 };

他のヒント

今思うとの回答は、質問の方法のご提案だと思うが右方向に行くことを除いて、また大多数の人員が共有するために集まって構造体やクラスおよび過去のことをしているので、引数としてのコンストラクタの基底クラスです。

ば、"共有"メンバーとして実施静員の派生クラスできても自動生成コードに由来します。XSLTはツールの自動生成の簡単なる。

一般的には、例表示しませんで"仮想"静員が目的のようにこれだけ実際に必要な継承-代わりに利用するべきである基底クラスで受け入れの適切な値をとるコンストラクタも単一のインスタンスの引数をそれぞれのサブタイプ"を通しのポインタでの重複を避け、共有データです。他の同様のアプローチを用テンプレートやパスとテンプレートの引数を提供するクラスのすべての関連する値(このこと"政策"パターン).

締結のための独自の例では、必要ありませんこのような"仮想"静ます。だと思うのは、コードを書いていを試してみてください精巧なります。

例私が述:

class BaseClass {
    public:
        BaseClass(const Descriptor& desc) : _desc(desc) {}
        string GetName() const { return _desc.name; }
        int GetId() const { return _desc.Id; }
        X GetX() connst { return _desc.X; }
        virtual void UseClass() = 0;
    private:
        const Descriptor _desc;
};


class DerivedClass : public BaseClass {
    public:
        DerivedClass() : BaseClass(Descriptor("abc", 1,...)) {}
        virtual void UseClass() { /* do something */ }
};

class DerDerClass : public BaseClass {
    public:
        DerivedClass() : BaseClass("Wowzer", 843,...) {}
        virtual void UseClass() { /* do something */ }
};

いて具体的に説明するソリューションも何の解決策の初期化の問題:

小さな変更を実装する事が出来ます設計上記のことなく新しいインスタンスの記述子をそれぞれのインスタンスを導出クラスです。

を作成できますシングルトンオブジェクトDescriptorMap、その単一のインスタンスの記述子でを構築する場合、派生物はこのように:

enum InstanceType {
    Yellow,
    Big,
    BananaHammoc
}

class DescriptorsMap{
    public:
        static Descriptor* GetDescriptor(InstanceType type) {
            if ( _instance.Get() == null) {
                _instance.reset(new DescriptorsMap());
            }
            return _instance.Get()-> _descriptors[type];
        }
    private:
        DescriptorsMap() {
            descriptors[Yellow] = new Descriptor("Yellow", 42, ...);
            descriptors[Big] = new Descriptor("InJapan", 17, ...)
            ...
        }

        ~DescriptorsMap() {
            /*Delete all the descriptors from the map*/
        }

        static autoptr<DescriptorsMap> _instance;
        map<InstanceType, Descriptor*> _descriptors;
}

現在ございました:

class DerivedClass : public BaseClass {
    public:
        DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.BananaHammoc)) {}
        virtual void UseClass() { /* do something */ }
};

class DerDerClass : public BaseClass {
    public:
        DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.Yellow)) {}
        virtual void UseClass() { /* do something */ }
};

末実行時にCランタイムを実行uninitializationsでも通話、デストラクタの静物を含むautoptr、削除当社のインスタンスDescriptorsMap.

そして今、単一のインスタンスの記述子を削除末ます。

この目的の派生クラスの供給に関する記述子"のデータ(に対して実施仮想機能)をされるようにしてくださいの基底クラスの非abstractは、作成インスタンスの適切な記述子です。

いHershiの提案テンプレートを使用しての"ベースです。からだを記述するので、音のような利用のためのテンプレートというよりも、サブクラス.

このテンプレートとして次のようにしていないためこ):


template <typename T>
class Object
{
public:

  Object( const T& newObject ) : yourObject(newObject) {} ;
  T GetObject() const { return yourObject } ;
  void SetObject( const T& newObject ) { yourObject = newObject } ;

protected:

  const T yourObject ;
} ;

class SomeClassOne
{
public:

  SomeClassOne( const std::vector& someData )
  {
    yourData.SetObject( someData ) ;
  }

private:

  Object<std::vector<int>> yourData ;
} ;

このご利用のテンプレートクラスの方法を変更データから必要に応じて内でのカスタムを使用するクラスのデータ共有の様々な面でテンプレートクラスです。

い意思を継承しなければならなくなるかもしれのリゾートの"喜び"を使用しvoid*ポインタをおBaseClass対応鋳物、等。

しかし、説明では、このように必要なテンプレートは継承関係を示します。

@Hershi:この問題は、この方法はそれぞれのインスタンスの各派生クラスのコピー、データは、費用がかかることがありました。

あとだれかうようなことになるだけ吐き出し-ボールなしで作成とえば、その考えは明確であるべきである).


#include <iostream>
#include <string>
using namespace std;

struct DerivedData
{
  DerivedData(const string & word, const int number) :
    my_word(word), my_number(number) {}
  const string my_word;
  const int my_number;
};

class Base {
public:
  Base() : m_data(0) {}
  string getWord() const { return m_data->my_word; }
  int getNumber() const { return m_data->my_number; }
protected:
  DerivedData * m_data;
};


class Derived : public Base {
public:
  Derived() : Base() {
    if(Derived::s_data == 0) {
      Derived::s_data = new DerivedData("abc", 1);
    }
    m_data = s_data;
  }
private:
  static DerivedData * s_data;
};


DerivedData * Derived::s_data = 0; 

int main()
{
  Base * p_b = new Derived();
  cout getWord() << endl;
}

に関しての疑問を削除する静的オブジェクト:の唯一のソリューションな利用スマートポインタのようなもの Boostの共通のポインタ.

そんでいる必要性を回避するために重複コードの葉の授業でなける中間基底クラスの基底クラスです。この中間のクラスの静的なデータは、すべての葉の授業から中間体基底クラスです。このこと前提とする一つの静的データ開催されますが、全ての導出クラスでは、いわからの例です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top