これが私が達成しようとしていることです:
さまざまなタイプのリンクリストを作成しようとしています。これを実現するには、ポリモーフィズムが最適な方法であると考えました。
AttributeBase と Attribute の 2 つのクラスがあります。AttributeBase は AttributeSet によって使用されます。これは、Attribute<T> のリンクされたリストの開始点と終了点を (AttributeBase* として) 格納し、リストを変更します。AttributeBase は Attribute<T> の基本クラスであり、ジェネリック ポインターを作成するためだけに設計されています。もちろん、Attribute<T> は、実際の値が格納される AttributeBase の特定の型です。各 Attribute<T> の主なデータは、継承された文字列 (属性の名前、または必要に応じて「キー」) と型 T の値です。
だから、これまでのところ私は(簡略化):
class AttributeBase
{
public:
AttributeBase() = delete;
AttributeBase* GetNext() { return next; };
AttributeBase* GetPrev() { return prev; };
std::string GetName() { return name; };
//Sometimes I need to get/set the value stored in a derived class
//But, how would I define the function here since the return
//type is of type T as defined in Attribute?
virtual ???? GetValue = 0;
virtual void SetValue(????) = 0;
friend class AttributeSet;
private:
AttributeBase* next = nullptr;
AttributeBase* prev = nullptr;
std::string name;
};
template <class T>
class Attribute : public AttributeBase
{
public:
Attribute( std::string _name, T _value ){ name = _name; value = _value };
T GetValue(){ return value; };
void Setvalue(T){ value = T; };
private:
T value;
};
class AttributeSet
{
public:
template <class T>
void Add(std::string,T); //Add an Attribute<T>(std::string,T) to the list
void Delete(std::string);
bool Contains(std::string _name); //Scan the list to determine if an
//attribute with name of _name exists
template <class T>
T Get(std::string); //Scan the list for 'name' and return
//AttributeBase*->GetValue()
private:
AttributeBase* start = nullptr;
AttributeBase* end = nullptr;
}
AttributeBase を一般的で非テンプレート化したままにしようとしたため (AttributeSet で厳密に型指定された開始ポインターと終了ポインターを回避するため)、これにより問題が発生します。仮想関数 BaseAttribute::GetValue() の現在のところ未指定の戻り値の型を指定するにはどうすればよいですか。最初に を使用してみauto
ましたが、コンパイル エラーが発生しました。
AttributeBase のインスタンスが実際に作成されない (そしてデフォルトのコンストラクターが削除される) ため、GetValue を省略して派生クラスで定義することが可能であると考えました。ただし、 *AttributeBase->GetValue() を試してみると、 GetValue() が AttributeBase で定義されておらず、サブクラスのみで定義されているため、エラーが発生します。AttributeBase は直接構築できないため、ポインターが派生クラス (唯一の派生型) を指す必要があることをコンパイラーが認識していると思われるでしょう。
したがって、GetValue() を使用するには、AttributeBase* を Attribute* にキャストできるように、前の値の型を事前に知っておく必要があります。AttributeBase 自体がテンプレート化され、値 T 型が含まれている場合、これは簡単です。次に、AttributeBase*->type にアクセスして、キャストする必要があるポインターの型を決定します。ただし、前述したように、AttributeBase をテンプレート化すると、オブジェクトの意図された使用が破棄されます。
おそらく、私はこれについて完全に間違った方法で行っています (またしても)。しかし、この時点で私はアイデアに行き詰まっています。どんな助けでも大歓迎です!