当前位置:  开发笔记 > 编程语言 > 正文

C++协变模板

如何解决《C++协变模板》经验,为你挑选了3个好方法。

我觉得之前已经问过这个问题,但我无法在SO上找到它,也无法在Google上找到任何有用的信息.也许"covariant"不是我正在寻找的词,但这个概念与函数的协变返回类型非常相似,所以我认为它可能是正确的.这是我想要做的,它给了我一个编译器错误:

class Base;
class Derived : public Base;

SmartPtr d = new Derived;
SmartPtr b = d; // compiler error

假设这些课程充分充实......我想你明白了.它不能转换SmartPtrSmartPtr某种不明原因.我记得在C++和许多其他语言中这是正常的,虽然目前我不记得为什么.

我的根本问题是:执行此赋值操作的最佳方法是什么?目前,我正在将指针拉出,将其SmartPtr明确地向上转换为基类型,然后将其包装为新SmartPtr的适当类型(请注意,这不会泄漏资源,因为我们的本地SmartPtr类使用侵入式引用计数).那是漫长而凌乱的,尤其是当我需要将SmartPtr另一个对象包裹起来时...任何快捷方式?



1> dirkgently..:

SmartPtr并且SmartPtrSmartPtr模板的两个不同的实例.这些新类不共享的继承问题BaseDerived做的.因此,你的问题.

执行此赋值操作的最佳方法是什么?

 SmartPtr b = d; 

不调用赋值运算符.这会调用copy-ctor(大多数情况下都会删除副本),就像你写的那样:

 SmartPtr b(d); 

提供需要SmartPtr并实现它的复制者.赋值运算符也是如此.你必须写出copy-ctor和op =记住SmartPtr的语义.


很大程度上取决于SmartPtr类的确切语义,例如它是否具有所有权转移,是否进行引用计数等.您必须写出copy-ctor和op =记住SmartPtr的语义.

2> MSN..:

复制构造函数和赋值运算符都应该能够采用不同类型的SmartPtr并尝试将指针从一个复制到另一个.如果类型不兼容,编译器会抱怨,如果它们兼容,你就解决了问题.像这样的东西:

template class SmartPtr
{
    ....
    template SmartPtr(const SmartPtr &blah) // same logic as the SmartPtr copy constructor

    template SmartPtr &operator=(const SmartPtr &blah) // same logic as the SmartPtr assignment operator
};



3> Luc Touraill..:

模板不是协变的,这很好; 想象在下列情况下会发生什么:

vector va;
va.push_back(new Apple);

// Now, if templates were covariants, a vector could be
// cast to a vector
vector & vf = va;
vf.push_back(new Orange); // Bam, we just added an Orange among the Apples!

要实现您要执行的操作,SmartPointer类必须具有模板化构造函数,该构造函数可以使用另一个SmartPointer或另一个类型的指针.你可以看一下boost :: shared_ptr,它就是这样做的.

template 
class SmartPointer {

    T * ptr;

  public:
    SmartPointer(T * p) : ptr(p) {}
    SmartPointer(const SmartPointer & sp) : ptr(sp.ptr) {}

    template 
    SmartPointer(U * p) : ptr(p) {}

    template 
    SmartPointer(const SmartPointer & sp) : ptr(sp.ptr) {}

    // Do the same for operator= (even though it's not used in your example)
};


我认为你的例子是一个错误的例子,因为它实际上并不完全是协变的_因为你可以在列表中推送像Orange这样的东西.如果公共接口只是_returns_ Fruit*,而不是_accepts_ Fruit*,它只会是协变的.C#提供"in"和"out"关键字,分别使泛型类型变为协变或逆变.它静态地强制使用类型来避免您描述的情况.
推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有