c++ 最后一堂课
class Temp
{
private:
~Temp() {}
friend class Final;
};
class Final : virtual public Temp
{
public:
void fun()
{
cout<<"In base";
}
};
class Derived : public Final
{
};
void main()
{
Derived obj;
obj.fun();
}
上面的代码试图实现不可继承的类(final)。但是使用上面的代码仍然可以创建导出的对象,为什么?
只有当 ctor 设为私有时才能实现所需的功能,我的问题是为什么在 dtor 私有的情况下无法实现?
class Temp
{
private:
~Temp() {}
friend class Final;
};
class Final : virtual public Temp
{
public:
void fun()
{
cout<<"In base";
}
};
class Derived : public Final
{
};
void main()
{
Derived obj;
obj.fun();
}
The above code tries to achieve non-inheritable class (final). But using above code the object of derived can still be created, why?
The desired functionality is achieved only if ctor made private, my question is why it is not achievable in case of dtor private?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当然,今天正确的方法是使用
final
关键字。例如:And of course the proper way to do it today is to use the
final
keyword. For example:奇怪的是重复出现的模板模式。使用私有继承。
并且您应该发现不可能从 X 派生任何内容,因为虚拟继承意味着最派生的类必须构造基类,但它无法访问它。
(我还没有测试过这段代码)。
Curiously recurring template pattern. Use private inheritence.
and you should find it impossible to derive anything from X because the virtual inheritence means that the most-derived class must construct the base class but it won't have any access to it.
(I haven't tested this code).
C++ FAQ 描述了不同的方法来实现这一目标 - 但从你的问题来看,我猜你'我已经读过它们了。 ;-)
(此外,
main
必须始终返回int
,而不是void
。)The C++ FAQ describes different ways to achieve this – but from your question I guess you’ve already read them. ;-)
(Also,
main
must always returnint
, nevervoid
.)派生类不会调用基类的私有析构函数,因此它不需要可见性。
将构造函数设为私有并仅提供静态生成器函数。
The derived class does not call the private destructor of the base class, hence it does not need visibility.
Make your constructors private and only provide a static generator function.
我修改了发布的原始代码并在 g++ 中验证了此代码:
结果:
$g++ one.cpp -o one -lm -pthread -lgmpxx -kgmp -lreadline 2>&1
one.cpp:在构造函数“Derived::Derived()”中:
one.cpp:8:9: 错误: 'Temp::Temp()' 是 private Temp() {
one.cpp:25:11: 错误:在此上下文中
派生类:public Final
one.cpp:11:9: error: 'Temp::~Temp()' is private ~Temp() {}
one.cpp:25:11: error: 在此上下文中
派生类:public Final
one.cpp:11:9:错误:'Temp::~Temp()' 是私有的
~Temp() {}
注意:最佳实践是不要将 void 与“main”一起使用。
谢谢,
I have modified the original code posted and verified this code in g++:
Result:
$g++ one.cpp -o one -lm -pthread -lgmpxx -kgmp -lreadline 2>&1
one.cpp: In constructor 'Derived::Derived()':
one.cpp:8:9: error: 'Temp::Temp()' is private Temp() {
one.cpp:25:11: error: within this context
class Derived: public Final
one.cpp:11:9: error: 'Temp::~Temp()' is private ~Temp() {}
one.cpp:25:11: error: within this context
class Derived : public Final
one.cpp:11:9: error: 'Temp::~Temp()' is private
~Temp() {}
Note: It's a best practice not use void with 'main'.
Thanks,
请注意,C++11 中存在不可继承的类,使用
final
关键字,在: base1, base2, ..., baseN
继承列表之前或开头之前指定{
如果类没有继承:通过一点宏魔法和一些编译器检测工作,可以将其抽象出来以在所有编译器上工作,或者最坏的情况下不执行任何操作。
Note that non-inheritable classes exist in C++11 using the
final
keyword, specified before the: base1, base2, ..., baseN
inheritance list or before the opening{
if the class inherits from nothing:With a little macro magic and some compiler-detection effort this can be abstracted away to work, or at worst do nothing, on all compilers.
好吧,对于这个程序(请提供正确的、可编译的示例)
Comeau Online 说,
因为,当有疑问时,我一直相信como(我只在其中发现了一个错误,但在其他编译器中发现了许多错误),我认为VC9(接受代码)有错误。 (从那个
void main()
我想你也使用 VC。)Well, for this program (pleasse provide correct, compilable examples)
Comeau Online says
Since, when in doubt, I always trust como (I have only ever found one error in it, but many in other compilers), I suppose VC9 (which accepts the code) is in error. (From that
void main()
I suppose you use VC, too.)