如何检测和断言特定类的虚拟继承?
我有一个实现引用计数的 C++ 类,并且我希望该类的所有用户仅从该类虚拟继承,以便没有对象最终拥有多个引用计数器。
我想要某种方法来在编译时或至少在运行时断言此要求。
有办法实现吗?
I have a C++ class that implements reference-counting and I want all users of this class to inherit from this class only virtually so that no object ends up with more than one reference counter.
I'd like some way to assert this requirment either during compile time or at least during runtime.
Is there a way to achieve that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
像这样的东西吗?
不过,需要将
this
传递给构造函数来捕获派生类型,这很遗憾。当然,故意迟钝的用户可以通过传递this
以外的其他内容来破坏它。Something like this?
It's a shame about needing to pass
this
to the constructor, though, to capture the derived type. And of course a wilfully obtuse user could subvert it by passing something other thanthis
.我认为包装类将是最简单的选择。而不是直接继承自 RefCounter 创建一个中间类。
那么一切都可以从 RefCounter 继承,而不需要关心虚拟继承。您甚至不必更改任何现有代码——
RefCounter
本身的虚拟继承应该是无害的。这当然并不能保证人们不会直接继承
RefCounterVirtPrivate_
,但这就是为什么我给它一个明显的名称。意外执行此操作比忘记virtual
关键字更难。I think wrapping the class would be the simplest option. Rather than directly inheriting from RefCounter create an intermediary class.
Then everything can inherit from
RefCounter
without any need to care about virtual inheritence. You don't even have to change any existing code -- virtual inheritence ofRefCounter
itself should be harmless.This of course doesn't guarantee people don't inherit from
RefCounterVirtPrivate_
directly, but that is why I've given it an obvious name. It's harder to accidentally do this than forget avirtual
keyword.通过一些技巧应该可以实现,但请考虑其含义:您正在设置策略,如果对象的引用计数器达到零,则该对象需要立即自毁。
根据您的应用程序,您可能希望将调用
delete this;
的确切时间留给对象的实现,即只有add_ref()
和release()
基类中的抽象函数(这使得一个具体实现通过适当的转换出现在所有接口 vtable 中),并将维护引用计数的负担交给具体类。It should be possible with some trickery, but consider the implications: you are setting the policy that the object needs to immediately self-destruct if its reference counter ever reaches zero.
Depending on your application, you might want to leave the exact time when it calls
delete this;
to the implementation of the object, i.e. only haveadd_ref()
andrelease()
abstract functions in the base class (which makes the one concrete implementation show up in all interface vtables with proper thunking) and place the burden of maintaining the reference count on the concrete class.