我有一个实现引用计数的 C++ 类,我希望这个类的所有用户只能虚拟地从这个类继承,这样任何对象都不会有多个引用计数器。
我想在编译时或至少在运行时用某种方法来断言这个要求。
有没有办法做到这一点?
我有一个实现引用计数的 C++ 类,我希望这个类的所有用户只能虚拟地从这个类继承,这样任何对象都不会有多个引用计数器。
我想在编译时或至少在运行时用某种方法来断言这个要求。
有没有办法做到这一点?
像这样的东西?
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
.
我认为包装类将是最简单的选择。而不是直接从 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
不小心这样做比忘记关键字更难。
应该有一些技巧,但考虑一下含义:您正在设置对象需要在其引用计数器达到零时立即自毁的策略。
根据您的应用程序,您可能希望在它调用delete this;
对象的实现时留下确切的时间,即在基类中只有add_ref()
和release()
抽象函数(这使得一个具体的实现出现在所有接口 vtable 中,并具有适当的 thunking)并将维护引用计数的负担放在具体类上。