2

したがって、次のクラスとメソッドを取得しました。

プロパティ: 型のメンバーを 1 つ持つint(名前はmTag)

TypedProperty : クラスから継承し、型のProperty呼び出されたメンバーをそれに追加します。mValueT

PropertyListstd::set : ofを保持し、 andメソッドPropertyを持つクラス。AddPrint

CheckSubsetstd::set : aが別のセットに含まれているかどうかをチェックするメソッド。

メソッドをどのように実装すればよいかわかりませんCheckSubsetset<Property>テンプレート メンバー ( ) へのアクセスを反復処理する方法がわからないためですmValue。私もそのincludes方法を使用しようとしましたが、うまくいきませんでした (うまくいったとしても、どのように機能したのかわかりません!)。メソッドにも同じ問題があり、PropertyList::Printどのキャストを使用すればよいかわかりません。およびメソッド
の実装に関するアドバイスをいただければ幸いです。CheckSubsetPrint

更新されたソース コード (ポインターを使用)

#include <string>
#include <iostream>
#include <set>
#include <algorithm>
#include <tr1/memory>

using namespace std;

/////////////////// Property Class //////////////////////

class Property
{
public:
    Property(){};
    Property(const int tag)
            : mTag(tag) {}
    virtual ~Property() {}
    int mTag;
    bool operator<(const Property &property) const
    {
        return mTag < property.mTag;
    }
};

/////////////////// TypedProperty Class /////////////////

template< typename T >
class TypedProperty : public Property
{
public:
    TypedProperty (const int tag, const T& value)
            : Property(tag), mValue(value){}
    T mValue;
};

/////////////////////////////////////////////////////////

typedef std::tr1::shared_ptr<Property> PropertyPtr;

/////////////////// PropertyList Class /////////////////

class PropertyList
{
public:
    PropertyList(){};
    virtual ~PropertyList(){};
    template <class T>
    void Add(int tag, T value) 
    {
    PropertyPtr ptr(new TypedProperty<T>(tag, value));
        mProperties.insert(ptr);
    }
    void Print()
    {
    for(set<PropertyPtr>::iterator itr = mProperties.begin(); itr != mProperties.end(); itr++)
    {
        cout << ((PropertyPtr)*itr)->mTag << endl; 
        // What should I do to print mValue? I do not know its type
        // what should *itr be cast to? 
    }
    }
    set<PropertyPtr> mProperties;
};

//////////////////// Check Subset ///////////////////////
/*
 * Checks if subset is included in superset 
 */
bool CheckSubset(set<PropertyPtr> &superset, set<PropertyPtr> &subset)
{
    // How can I iterate over superset and subset values while I do not know
    // the type of mValue inside each Property?
    // I also tried the following method which does not seem to work correctly
    return includes(superset.begin(), superset.end(), 
            subset.begin(), subset.end());
}

int main()
{
    PropertyList properties1;
    properties1.Add(1, "hello");
    properties1.Add(2, 12);
    properties1.Add(3, 34);
    properties1.Add(4, "bye");

    properties1.Print();

    PropertyList properties2;
    properties2.Add(1, "hello");
    properties2.Add(3, 34);


    if(CheckSubset(properties1.mProperties, properties2.mProperties)) // should be true
        cout << "properties2 is subset!" << endl;

    PropertyList properties3;
    properties3.Add(1, "hello");
    properties3.Add(4, 1234);

    if(CheckSubset(properties1.mProperties, properties3.mProperties)) // should be false
        cout << "properties3 is subset!" << endl;
}
4

2 に答える 2

5

あなたが望むことは、現在のデザインでは実現できません。

あなたのアプローチは で失敗しstd::set<Property>ます。

std::set<Property>スライスします。つまり、パーツのみをコピーし、追加のメンバーPropertyをコピーするのを忘れます。TypedProperty<T>

その結果、 内PropertyList::print()では、mValue にアクセスする方法がありません。

TypedProperty<T>s を 内に格納する場合std::setは、ある種のポインターを使用する必要があります。std::set<Property*>つまり、 またはスマート ポインター バージョンのいずれかです。

于 2012-10-29T12:34:46.130 に答える
1

Printのメソッドの問題を解決するために、タグと値を出力するクラスのメソッドをPropertyList作成できます。PrintTypedProperty

しかし、mValueいくつかの操作を実行したいアクセスの問題については、通常のタイプとテンプレートを使用してmValue、親クラスPropertyをテンプレートタイプTypedProperty(望ましくないようです)に関与させずに取得する方法を考えることはできません。ただし、のアドレスを取得してmValueキャストするとvoid*、型の問題を解消できます。このようにすると、ポインタの値をvoid*指すことができないため、親レベルでポインタを操作できないという別の問題に直面します。したがって、ポインタを受け取り、それを子で定義された型にキャストして目的の操作を実行するメソッド(によって実装されるTypedProperty)を作成する必要があります。void*

たとえば、次のコードでは、aの値が同じタイプ(メソッド)TypedPropertyの別の値と等しいかどうかを確認したいとしました。IsEqual

CheckSubsetこれで、を使用して簡単に実装できますIsEqual(2つの要素をチェックすると次のようになります:) superItr->IsEqual(subItr->GetValue())

class Property
{
    public:
        Property(){};
        Property(const int tag)
            : mTag(tag) {}
        virtual ~Property() {}
        virtual void* GetValue() = 0;
        virtual bool IsEqual(void* value) = 0;
        virtual void Print() = 0;
        int mTag;
        bool operator<(const Property &property) const
        {
            return mTag < property.mTag;
        }
};


template< typename T >
class TypedProperty : public Property
{
    public:
        TypedProperty (const int tag, const T& value)
            : Property(tag), mValue(value){}
        void* GetValue()
        {
            return &mValue;
        }
        bool IsEqual(void* value)
        {
            return *((T*)value) == mValue;
        }
        void Print()
        {
            cout << "Tag: " <<  mTag << ", Value: " << mValue << endl;
        }
        T mValue;
};

typedef std::tr1::shared_ptr<Property> PropertyPtr;

class PropertyList
{
    public:
        PropertyList(){};
        virtual ~PropertyList(){};
        template <class T>
            void Add(int tag, T value) 
            {
                PropertyPtr ptr(new TypedProperty<T>(tag, value));
                mProperties.insert(ptr);
            }
        void Print()
        {
            cout << "-----------" << endl;
            for(set<PropertyPtr>::iterator itr = mProperties.begin(); itr != mProperties.end(); itr++)
            {
                (*itr)->Print();
            }
        }
        set<PropertyPtr> mProperties;
};
于 2012-10-29T13:56:14.677 に答える