13
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 私有的情况下无法实现?

4

7 回答 7

30

final请注意,在 C++11 中使用关键字存在不可继承的类,如果类从无继承,则在: base1, base2, ..., baseN继承列表之前或在打开之前指定:{

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

通过一点宏魔法和一些编译器检测工作,可以将其抽象为在所有编译器上工作,或者最坏的情况是什么都不做。

于 2011-11-20T08:16:37.553 回答
11

好吧,对于这个程序(请提供正确的、可编译的示例)

#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。)

于 2009-09-02T08:39:02.187 回答
5

Curiously recurring template pattern. Use private inheritence.

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

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

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

于 2012-02-01T16:30:39.007 回答
5

C++ FAQ 描述了实现这一目标的不同方法——但从你的问题我猜你已经阅读了它们。;-)

(此外,main必须始终返回int,从不void。)

于 2009-09-02T08:32:52.623 回答
4

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

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

  void bar() {
     // ...
  }
};
于 2013-02-28T16:42:25.350 回答
0

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

将您的构造函数设为私有,并且仅提供静态生成器函数。

于 2009-09-02T08:35:19.293 回答
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>&1

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

one.cpp:25:11:错误:在此上下文类中派生:公共最终

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

one.cpp:25:11:错误:在此上下文类中派生:公共最终

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

注意:最好不要将 void 与“main”一起使用。

谢谢,

于 2013-12-20T08:12:51.387 回答