final class in c++

2019-02-06 06:26发布

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?

7条回答
走好不送
2楼-- · 2019-02-06 06:55

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

查看更多
Emotional °昔
3楼-- · 2019-02-06 06:59

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

查看更多
【Aperson】
4楼-- · 2019-02-06 07:01

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

查看更多
走好不送
5楼-- · 2019-02-06 07:03

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.

查看更多
戒情不戒烟
6楼-- · 2019-02-06 07:03

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.

查看更多
冷血范
7楼-- · 2019-02-06 07:08

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,

查看更多
登录 后发表回答