3

我有一个IStructure由许多类派生的基类。

其中一些类“引用”其他IStructure类。例如,我的班级class GuiButton : public IStructure有一个成员Textstring(也派生自IStructure)。

现在我只是对此闪闪发光,所以我可以直截了当,所以这对你们中的一些人来说可能看起来很奇怪。我想要一个引用IStructure. 例如:

class GuiButton : public IStructure {
public:
    Reference<Textstring> Text;
};

我知道你们中的一些人可能想知道我为什么不这样做Textstring* Text。这是因为其中一些引用是“外部的”。Reference模板类仅保存有关IStructure(即名称等)的信息。其中一些类非常大,实例化整个类以仅使用该Name属性是没有意义的。那有意义吗?

所以现在我的问题:

class Textstring : public IStructure;

我可以Textstring使用我的模板来引用 a:

Reference<Textstring> Text;

现在问题来了:我有一些方法要求我向上转换到“IStructure”,例如:

void RegisterReference(Reference<IStructure> &reference);

所以我不能这样做:

Reference<Textstring> txt("TextName");
RegisterReference(txt); // error

我知道我可以通过不Reference作为模板来解决这个问题,但我真的很想这样做,因为它更容易理解和知道引用的类型。

有什么方法可以做到这一点?

谢谢你的帮助!

-亚历克斯

4

2 回答 2

3

正如@dasblinkenlight 建议的那样,您可以模板化您的库函数。或者,您可以在Reference类中添加一些“差异”:

template<typename T>
class Reference
{
    // ...
public:
    template<typename U>
    Reference(Reference<U> const & r) {
        // "copy" r into *this
    }
};

或使用转换运算符

template<typename T>
class Reference
{
    // ...
public:
    template<typename U>
    operator Reference<U>() {
        // convert Reference<T> into Reference<U>
    }
};

这种方法的缺点是每次需要向上转换时实际上都是在创建新对象。

编辑

感谢 Luc Danton 指出这一点。我编写的代码处理方式比向上转换要多。它会做任何可用的转换。为了更好地限制事情,我们可以做这样的事情(在 C++11 中):

template<typename T>
class Reference
{
    // ...
public:
    template<typename U,
      typename = typename std::enable_if<std::is_base_of<T, U>::value>::type>
    Reference(Reference<U> const & r) {
        // "copy" r into *this
    }
};
于 2012-09-01T01:21:05.117 回答
2

您可以在 的类型参数上使您的函数成为模板Reference,如下所示:

template <typename R>
void RegisterReference(Reference<R> &r);
于 2012-09-01T01:13:34.293 回答