模板,继承和虚拟方法(C ++) [英] Templates, Inheritance, and Virtual Methods (C++)
问题描述
我想写一个通用的设置管理器。设置来自INI文件,可以是整数或字符串。我想要能够存储这些设置的向量,所以我可以通过它们迭代找到所需的一个,并提取其值。
I am trying to write a generic settings manager. Settings come from an INI file and can be integer or string. I want to be able to store a vector of these settings, so I can iterate through them to find the desired one, and extract its value.
我想能够写入如下:
// Desired usage:
Settings settings; // A container class, defined below
settings.add(new Setting<string>("shipName", "HAL"));
settings.add(new Setting<int> ("shipYear", 2001));
// Different return types:
string shipName = settings.getSetting("shipName")->getValue();
int shipYear = settings.getSetting("shipYear")->getValue();
我有3个课程:
-
AbstractSetting,它是所有设置类的母亲。我需要这个,所以我可以有一个一致的类型存储在向量。
AbstractSetting, which is the mother of all setting classes. I need this so I can have a consistent type to store in a vector.
设置,一个模板类继承AbstractSetting。这里我可以将设置数据存储为字符串或整数。
Setting, a templated class that inherits from AbstractSetting. Here I can store the setting data as either string or integer.
设置,用于保存设置的容器类, / p>
Settings, a container class for holding my settings, which takes care of storage and retrieval.
方法主要是getters / setters。因为实现是显而易见的,我为了简洁省略了它们。
Methods are mostly getters/setters. Since implementations are obvious, I've omitted them for the sake of brevity.
我的问题是我在AbstractSetting中放置什么,以允许我有不同的实现返回类型)getValue()?
My question is what do I put in AbstractSetting to allow me to have different implementations (with different return types) for getValue()?
class AbstractSetting
{
private:
string mName;
public:
AbstractSetting(const string &name); // Constructor
// What does here? Need to declare getValue somehow
};
////////////////////////////////////////
// Sublcasses of AbstractSetting, one for each T
template <class T>
class Setting : public AbstractSetting
{
private:
T mValue;
public:
Setting<T>(const string &name, const T &value);
void setValue(const T &value);
T getValue();
};
////////////////////////////////////////
// Container for all our settings
class Settings
{
private:
Vector<AbstractSetting *> mSettings;
public:
const AbstractSetting *getSetting(const string &name) const;
void add(AbstractSetting *setting); // Store new setting
};
推荐答案
我想你必须告诉编译器什么类型你期望,你可以这样做这样做:
I think you will have to tell the compiler what type you expect, you can do this by doing something like this:
class AbstractSetting
{
private:
string mName;
public:
AbstractSetting(const string &name); // Constructor
template <typename T>
T& getTheValue()
{
Settings<T>* upcast = dynamic_cast<Settings<T>*>(this);
if (!upcast)
; //throw your exception
return upcast->getValue();
}
template <typename T>
T const& getTheValue() const
{
Settings<T>* upcast = dynamic_cast<Settings<T>*>(this);
if (!upcast)
; //throw your exception
return upcast->getValue();
}
};
并使用以下命名:
string & value = settings.getSettings("strName").getTheValue<string>();
int otherValue = settings.getSettings("intName").getTheValue<int>();
如果不想指定返回类型,可以通过引用传递一个变量像这样:
If you do not want to specify the return type, you can pass a variable by reference, by doing something like this:
class AbstractSetting
{
private:
string mName;
public:
AbstractSetting(const string &name); // Constructor
template <typename T>
void getTheValue(T& ret)
{
Settings<T>* upcast = dynamic_cast<Settings<T>*>(this);
if (!upcast)
; //throw your exception
ret = upcast->getValue();
}
};
并使用它:
string value;
int otherValue;
settings.getSettings("stringName").getTheValue(value); // will do a copy, so this is kind of bad, avoid this by using pointer.
settings.getSettings("intName").getTheValue(otherValue);
这篇关于模板,继承和虚拟方法(C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!