简体   繁体   English

模板类和基类?

[英]Template classes and base classes?

I have a base class IStructure which is derived by many classes. 我有一个基类IStructure ,由许多类派生。

Some of these classes 'reference' other IStructure classes. 其中一些类'引用'其他IStructure类。 For example, my class class GuiButton : public IStructure has a member of Textstring (which derives from IStructure , as well). 例如,我的类class GuiButton : public IStructure有一个Textstring的成员(它也来自IStructure )。

Now I'm just glistening over this so I can get to the point, so this may seem weird to some of you. 现在我只是闪闪发光,所以我可以说到这一点,所以这对你们中的一些人来说似乎很奇怪。 I would like to have a template class 'Reference' that references an IStructure . 我想有一个引用IStructure的模板类'Reference'。 For example: 例如:

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

I know some of you might be wondering why I just don't do Textstring* Text . 我知道有些人可能想知道我为什么不做Textstring* Text This is because some of these references are "external". 这是因为其中一些引用是“外部的”。 The Reference template class only holds information about the IStructure (ie. Name, etc.). Reference模板类仅保存有关IStructure信息(即名称等)。 Some of these classes are insanely big and it would be pointless to instantiate that whole class to only use the Name property and what not. 其中一些类非常庞大,将整个类实例化为仅使用Name属性和不使用Name属性是没有意义的。 Does that make sense? 那有意义吗?

So now to my question: 所以现在我的问题:

class Textstring : public IStructure;

I can reference a Textstring by using my template: 我可以使用我的模板引用Textstring

Reference<Textstring> Text;

Now here's the issue: Some methods I have require me to upcast to `IStructure', for example: 现在问题出在这里:我需要的一些方法要求我将其转换为“IStructure”,例如:

void RegisterReference(Reference<IStructure> &reference);

So I couldn't do this: 所以我不能这样做:

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

I know I can cure this by not having Reference be a template, but I would really like to because it makes it easier to understand and know what type the reference is. 我知道我可以通过不使用Reference作为模板来解决这个问题,但我真的很想,因为这样可以更容易理解并知道引用的类型。

What are some ways I can accomplish this? 我有什么方法可以做到这一点?

Thanks for your help! 谢谢你的帮助!

-Alex -Alex

As @dasblinkenlight suggest, you could templatize your library functions. 正如@dasblinkenlight建议的那样,您可以模板化您的库函数。 Or, you can add some "variance" to the Reference class: 或者,您可以向Reference类添加一些“方差”:

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

Or with conversion operators 或者使用转换运算符

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

The downside of this approach is that you're actually creating new objects each time you need to upcast. 这种方法的缺点是,每次需要向上转换时,您实际上都在创建新对象。

Edit 编辑

Thanks to Luc Danton for pointing this out. 感谢Luc Danton指出这一点。 The code as I have written handles way more than upcasts. 我编写的代码处理的方式不仅仅是upcast。 It'll do whatever conversions are available. 它会做任何可用的转换。 To restrict things a little more nicely, we could do something like this (in C++11): 为了更好地限制事物,我们可以做这样的事情(在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
    }
};

You can make your function a template on the type parameter of the Reference , like this: 您可以使您的函数成为Reference的type参数的模板,如下所示:

template <typename R>
void RegisterReference(Reference<R> &r);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM