c ++中的最终类

Lea*_*ner 13 c++ inheritance final virtual-inheritance

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();
}
Run Code Online (Sandbox Code Playgroud)

上面的代码试图实现不可继承的类(final).但是使用上面的代码仍然可以创建派生的对象,为什么呢?

只有当ctor私有化时才能实现所需的功能,我的问题是为什么在dtor私有的情况下无法实现?

Jef*_*den 30

请注意,C++ 11中存在不可继承的类final,使用在: base1, base2, ..., baseN继承列表之前指定的关键字,或者在开始之前,{如果类继承自任何内容:

class Final final { };
class Derived : public Final { }; // ERROR
Run Code Online (Sandbox Code Playgroud)

通过一点宏观魔法和一些编译器检测工作,这可以在所有编译器上被抽象出去工作,或者最坏的情况下无所事事.


sbi*_*sbi 10

那么,对于这个程序(pleasse提供正确,可编译的例子)

#include <iostream>

class Temp
{
private:
    ~Temp() {}
    friend class Final;
};

class Final : virtual public Temp
{
public:
    void fun() { std::cout<<"In base"; }
};

class Derived : public Final {};

int main() {
    Derived obj;
    obj.fun();
}
Run Code Online (Sandbox Code Playgroud)

Comeau Online

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 16: error: "Temp::~Temp()" (declared at line 6) is inaccessible
  class Derived : public Final {
                         ^
          detected during implicit generation of "Derived::Derived()" at line
                    21

"ComeauTest.c", line 16: error: "Temp::~Temp()" (declared at line 6) is inaccessible
  class Derived : public Final {
        ^
          detected during implicit generation of "Derived::~Derived()" at line
                    21

2 errors detected in the compilation of "ComeauTest.c".
Run Code Online (Sandbox Code Playgroud)

因为,当有疑问时,我总是信任como(我只发现过一个错误,但其他编译器中有很多错误),我想VC9(接受代码)是错误的.(从那以后void main()我想你也使用VC.)

  • @frieto:访问保护是纯粹的编译器前端功能.这没有什么神奇之处.一旦前端接受代码,后端只是对作为dtor的函数注入一个调用. (3认同)
  • @frieto:嗯,其实我_am_说他们没有考虑虚拟继承来检查dtor访问权限.(尽管如此,他们也为ctor做了.)而且这个问题很复杂,以至于我们大多数人都认为VC不管是对还是错. (2认同)

小智 6

当然,今天正确的方法是使用关键字final。例如:

class Foo final {
public:
  Foo() {}
  ~Foo() {}

  void bar() {
     // ...
  }
};
Run Code Online (Sandbox Code Playgroud)


Kon*_*lph 5

C++ FAQ描述了实现这一目标的不同方法 - 但是根据你的问题,我猜你已经阅读过了.;-)

(此外,main必须始终返回int,永远不会void.)

  • 既然`Derived`必须调用`Temp`的ctor,它也不必调用它的dtor吗? (2认同)
  • @sbi:我认为*不同的规则适用于析构函数,但是你的Comeau输出却是相反的情况.无论如何我会回答我的答案,因为它引用了常见问题,并提到"void"在`main`上无效.否则,你的答案似乎是钉在它上面.看看VS编译的代码如何表现应该很有趣,特别是如果在多个继承层次结构中多次调用虚拟基类的析构函数. (2认同)

Cas*_*Cow 5

好奇地反复出现模板模式.使用私有继承.

template< typename T > class Final
{
protected:
    Final() {}
    Final( Final const& ) {}
};

class X : private virtual Final<X>
{
  // whatever I want to do
};
Run Code Online (Sandbox Code Playgroud)

并且您应该发现无法从X派生任何内容,因为虚拟继承意味着派生程度最高的类必须构造基类,但它不具有对它的任何访问权限.

(我没有测试过这段代码).