final class in c++

我的梦境 提交于 2019-11-30 08:40:30

Well, for this program (pleasse provide correct, compilable examples)

#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 says

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

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

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:

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

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.

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

Konrad Rudolph

The C++ FAQ describes different ways to achieve this – but from your question I guess you’ve already read them. ;-)

(Also, main must always return int, never void.)

And of course the proper way to do it today is to use the final keyword. For example:

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

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

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.

I have modified the original code posted and verified this code in 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;
}

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,

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!