c ++中的最终类

时间:2009-09-02 08:27:47

标签: 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();
}

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

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

7 个答案:

答案 0 :(得分:30)

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

class Final final { };
class Derived : public Final { }; // ERROR

通过一些宏魔术和一些编译器检测工作,这可以被抽象出去工作,或者最糟糕的是什么都不做,在所有编译器上。

答案 1 :(得分: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();
}

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".

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

答案 2 :(得分:5)

C ++常见问题解答描述different ways来实现这一目标 - 但是根据您的问题,我猜您已经阅读过它们了。 ; - )

(另外,main必须始终返回int,而不是void。)

答案 3 :(得分:5)

奇怪地反复出现模板模式。使用私有继承。

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

class X : private virtual Final<X>
{
  // whatever I want to do
};

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

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

答案 4 :(得分:4)

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

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

  void bar() {
     // ...
  }
};

答案 5 :(得分:0)

派生类不会调用基类的私有析构函数,因此它不需要可见性。

使构造函数成为私有,只提供静态生成器函数。

答案 6 :(得分:0)

我修改了发布的原始代码并在g ++中验证了此代码:

class Temp
{
private:
    Temp() {
        cout << "In Temp Class ctor" << endl;
    }
    ~Temp() {}
    friend class Final;
};

class Final : virtual public Temp
{
public:

    void fun()
     {
         cout<<"In base";
     }
};

class Derived : public Final
{
};

int main()
{
    Derived obj;
    obj.fun();

    return 0;
}

结果: $ g ++ one.cpp -o one -lm -pthread -lgmpxx -kgmp -lreadline 2&gt;&amp; 1

one.cpp:在构造函数'Derived :: Derived()'中: one.cpp:8:9:错误:'Temp :: Temp()'是私有的Temp(){

one.cpp:25:11:错误:在此上下文中     class Derived:public Final

one.cpp:11:9:错误:'Temp :: ~Temp()'是私有的~Temp(){}

one.cpp:25:11:错误:在此上下文中     class Derived:public Final

one.cpp:11:9:错误:'Temp :: ~Temp()'是私有的     ~Temp(){}

注意:最好不要在'main'中使用void。

谢谢,