9

我有一个实现引用计数的 C++ 类,我希望这个类的所有用户只能虚拟地从这个类继承,这样任何对象都不会有多个引用计数器。

我想在编译时或至少在运行时用某种方法来断言这个要求。

有没有办法做到这一点?

4

3 回答 3

9

像这样的东西?

struct RefCounter {
    template <typename T>
    RefCounter(T *) {
        BOOST_STATIC_ASSERT(boost::is_virtual_base_of<RefCounter, T>);
    }
};

struct GoodClass : virtual RefCounter {
    GoodClass() : RefCounter(this) {}
};

struct BadClass : RefCounter {
    BadClass() : RefCounter(this) {}
};

但是,需要传递this给构造函数来捕获派生类型是一种耻辱。当然,一个故意迟钝的用户可以通过传递除this.

于 2011-12-19T10:04:21.550 回答
5

我认为包装类将是最简单的选择。而不是直接从 RefCounter 继承创建一个中间类。

struct RefCounterVirtPrivate_
{
    int count;

    RefCounterVirt()
        : count( 0 )
    { }
};

struct RefCounter : public virtual RefCounterVirtPrivate_
{
};

struct A : public RefCounter { };
struct B : public RefCounter { };
struct C : public A, public B { };

然后一切都可以继承RefCounter而无需关心虚拟继承。您甚至不必更改任何现有代码——RefCounter其自身的虚拟继承应该是无害的。

这当然不能保证人们不会RefCounterVirtPrivate_直接继承,但这就是为什么我给它起了一个明显的名字。virtual不小心这样做比忘记关键字更难。

于 2011-12-19T11:29:18.043 回答
0

应该有一些技巧,但考虑一下含义:您正在设置对象需要在其引用计数器达到零时立即自毁的策略。

根据您的应用程序,您可能希望在它调用delete this;对象的实现时留下确切的时间,即在基类中只有add_ref()release()抽象函数(这使得一个具体的实现出现在所有接口 vtable 中,并具有适当的 thunking)并将维护引用计数的负担放在具体类上。

于 2011-12-19T09:56:53.610 回答