[英]Best way to read a files contents and separate different data types into separate vectors in C++
[英]Best way for derived classes to carry different data types in C++
在C ++中提供一個接口的最優雅的方法是,該接口接受派生類類型,這些派生類類型帶有不同的數據類型成員,這些成員隨后需要被檢索。 下面的示例說明了這一點,其中Container類提供了用於“發布” Item的方法,該方法將是BaseItem的某種派生變體。 稍后,我想取回派生的Item並提取其值。
我想要的主要事情是讓Container接口(發布和接收)在將來保持不變,同時允許定義和“傳遞”不同的“ Item”派生類型。 模板在某種程度上會更好嗎? 我寧願不使用RTTI。 也許對此有一些簡單,優雅的答案,但是現在我正在努力思考。
class ItemBase {
// common methods
};
class ItemInt : public ItemBase
{
private:
int dat;
public:
int get() { return dat; }
};
class ItemDouble : public ItemBase
{
private:
double dat;
public:
double get() { return dat; }
};
class Container {
public:
void post(int postHandle, ItemBase *e);
ItemBase* receive(int handle); // Returns the associated Item
};
int main()
{
ItemInt *ii = new IntItem(5);
Container c;
c.post(1, ii);
ItemInt *jj = c.receive(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
絕對是通用編程而不是繼承的候選人。 請記住,當您希望對不同數據類型進行相同處理時,泛型(模板)是理想的選擇。 您的ItemInt和ItemDouble類違反了OO設計原則(get()方法根據實際的子類型返回不同的數據類型)。 通用編程就是為此而構建的。 唯一的其他答案是標記數據類型,我個人避免使用類似瘟疫的方法。
您的Container類看起來像一個std :: map。 在我看來,您的ItemBase類只是通用基類“ Object”的另一個名稱,我認為它與void *並沒有多大不同(或優於void *)。 我會避免嘗試在單個容器中包含不同類型的項目。 如果您的設計似乎需要這樣做,那么我會重新考慮您的設計。
怎么樣?
template<typename T>
class Item
{
private:
T dat;
public:
T get() { return dat; }
};
class Container {
public:
template<typename T>
void post(int postHandle, Item<T> *e);
template<typename T>
Item<T>* receive(int handle); // Returns the associated Item
};
int main()
{
Item<int> *ii = new Item<int>(5);
Container c;
c.post(1, ii);
Item<int> *jj = c.receive<int>(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
純模板方法不起作用,因為您顯然希望在容器中使用混合類型。 您可以使用Boost的any
盡管我認為您需要恢復實際值。 在這種情況下,我認為需要的是一個基類,該基類暴露了類型無關的方法和虛方法以及一個模板化派生類,以容納實際項目:
class Base {
public:
virtual ~Base() {}
virtual void post() = 0;
};
template <typename T>
class Item: public Base {
public:
Item(T const& value): value_(value) {}
void post() { std::cout << "posting " << this->value_ << "\n"; }
private:
T value_;
};
這種方法避免了需要為另一個值類型編寫任何派生的Item
類。 為了使創建這些野獸更加容易,您可能還希望創建一個合適的創建函數,例如
template <typename T>
std::unique_ptr<Base> make_item(T const& value) {
return std::unique_ptr<Base>(new Item<T>(value));
}
返回一個std::unique_ptr<Base>
以確保釋放分配的對象(如果您不使用C ++ 2011,則可以使用std::auto_ptr<T>
)。 可以輕松地將該類型轉換為其他指針類型,例如,轉換為更適合放入容器的std::shared_ptr<Base>
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.