模板,继承和虚拟方法(C ++) [英] Templates, Inheritance, and Virtual Methods (C++)

查看:138
本文介绍了模板,继承和虚拟方法(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个课程:


  1. AbstractSetting,它是所有设置类的母亲。我需要这个,所以我可以有一个一致的类型存储在向量。

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆