2011-06-04 90 views
2

我有一個問題,一直困擾着我一段時間&我還沒有想出一個解決方案。我想創建一個容器類來存儲對象&根據它們的一個成員變量值對它們進行排序。因此,如果我有一班學生(使用成員變量int studentID),我想根據他們的studentID值按升序將它們存儲在我的Container類中。我已經將容器類作爲模板類,以便我可以在任何項目中使用任何類。存儲一個指向對象成員變量的指針

我的容器類問題:我無法存儲對象的指針(例如學生對象)。更準確的問題是我無法將引用(?)存儲到對象成員變量(例如,引用/指向學生的studentID變量的指針)。

這個問題一直令我很煩,我年齡&任何信息或建議將不勝感激。有沒有辦法讓我的下面的Container類存儲指針對象成員變量?有沒有不同的方法來創建一個可以通過它們的成員變量排序的對象的容器?

#include <iostream> 

using namespace std; 

template <typename Object, typename dataType> 
class Collection 
{ 
    public: 

     Collection(dataType Object::*nMemberVariable) 
     { 
      memberVariable = nMemberVariable; 
     } 

     bool store(Object* o) 
     { 
       // check that o is not a NULL pointer & not already present in maps 
       if (o==NULL || instanceVarMap.find(o->*memberVariable) != instanceVarMap.end()) 
       { 
        return false; 
       } 

       instanceVarMap.insert(o->*memberVariable, o); 
       return true; 
     } 

    private: 
     dataType Object::* memberVariable; 
     std::map <dataType, Object*>  instanceVarMap; 
}; 


struct FoodItem 
{ 
    unsigned int ID; 
    string name; 
    double price; 
}; 


int main() 
{ 

    // I am attempting to store a pointer to an objects member variable 
    // this is so I can create a custom container class(like a map or vector) that 
    // sorts its contents (which are FoodItem objects) according to their member variable values 
    // so a container could sort all its elements according to a FoodItems ID value or name value 

    Collection <FoodItem*> foodCol(&FoodItem::name); 

    string nNames[]   = {"a", "b", "c", "d"}; 
    double nPrices[]   = {1.1, 2.2, 3.3, 4.4}; 

    for (int i=0; i<4; i++) 
    { 
     FoodItem *f = new FoodItem() { i, nNames[i], nPrices[i] }; 
     foodCol.store(f); 
    } 

    // Note storing an ACTUAL object is possible with this class 
    Collection <FoodItem*> foodCol(&FoodItem::name); 
    FoodItem f(1, "a", 4); 
    foodCol.store(f); 

    system("PAUSE"); 
    return 0; 
} 

回答

0

首先,你Collection模板化的兩類:ObjectdataType。但是,您始終只填寫第一個,如Collection <FoodItem*> foodCol(...)。更改過:

Collection <FoodItem*,string> foodCol(&FoodItem::name); 

接下來,

FoodItem f(1, "a", 4); 
foodCol.store(f); 

不應該編譯。你期待Object*,而ObjectFoodItem*,所以最後你期待FoodItem**,但你傳遞的是一個簡單的FoodItem。改變store的定義,所以在上面的例子中,它只需要一個const Object&並通過&f。由於ObjectFoodItem*,因此您的store預計會有FoodItem* const&,即指向FoodItem*指針的恆定引用。正是我們想要的。

其餘的看起來很好,據我所見,特別是成員數據指針是正確的。但我可能會忽略一些東西,這裏很晚...

1

如果我正確地理解了這個問題,你問的問題似乎是setstd::set可以將謂詞排序爲第二個模板參數。 如果您準備比較目標成員進行排序的謂詞, set中的元素將根據該成員進行排序。
例如:

#include <set> 

struct FoodItem { 
    unsigned int ID; 
    double price; 
}; 

template< class C, class T, T C::* M > 
struct member_comparator { // predicate 
    bool operator()(C const* x, C const* y) const { return x->*M < y->*M; } 
}; 

int main() { 
    FoodItem a = { 1, 2.5 }, b = { 2, 1.5 }; 
    // a set sorted by ID 
    std::set< FoodItem* 
      , member_comparator< FoodItem, unsigned, &FoodItem::ID > > s_ID; 
    s_ID.insert(&a); 
    s_ID.insert(&b); 
    // a set sorted by price 
    std::set< FoodItem* 
      , member_comparator< FoodItem, double, &FoodItem::price > > s_price; 
    s_price.insert(&a); 
    s_price.insert(&b); 
} 

這裏是關於ideone測試。

相關問題