views:

763

answers:

5
+9  Q: 

final class in c++

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?

+2  A: 

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

Konrad Rudolph
(Removed bogus from my answer.)
Konrad Rudolph
Since `Derived` has to call the ctor of `Temp`, doesn't it have to call its dtor, too?
sbi
@sbi: I *thought* that different rules applied to the destructor but your Comeau output makes a case for the opposite. I’ll let my answer stand anyway since it references the FAQ and mentions that `void` isn’t valid on `main`. Otherwise, your answer seems to nail it. It should be interesting to see how the code compiled by VS behaves, in particular if the destructor of a virtual base class gets called multiple times in multiple inheritance hierarchies.
Konrad Rudolph
@Konrad: I also only guessed, but como confirmed my guess, not yours. `:)` VC accepts my code (I should have written this in my answer. Sorry.) I suppose that's a bug in VC.
sbi
@Konrad: I tested that and VC++ do it ok, virtual inheritance works ok. The problem is only in access permission. -1 for saying "Derived doesn’t need to know Temp’s destructor". Why then should he use virtual inheritance?
fnieto
A: 

non-inheritable, final, classes do not exist in C++.

elcuco
Yep. This is why he tries to emulate the behavior.
sbi
A: 

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.

David Allan Finch
He knows that it works then. He asks why it doesn't work when he makes the dtor private, too.
sbi
Ok - see my answer after change.
David Allan Finch
Actually this is a more interesting question that it initially look.
David Allan Finch
@David: Since the derived class calls the ctor, shouldn't it also have to call the dtor?
sbi
I am not sure that a constructor or destructor call down. I think that new / delete does that, hence it probably looks at the visibility of only the created class. If you can't create something you can't destroy it.
David Allan Finch
+7  A: 

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

sbi
Yes i used VC.. Thanks for pointer, I think i will try will gcc also.
Learner
+1 gcc also complains about that code. How can VS destroy Derived not having access to Temp, what is required having virtual inheritance in Final????
fnieto
@frieto: Access protection is a pure compiler front end feature. There's no magic to it. Once the front end accepts the code, the back end simply injects a call to the function that is the dtor.
sbi
@sbi: Ohh yes, but its a basic rule. Is like they are not taking into account the virtual inheritance to check access permission.
fnieto
@frieto: Well, in fact I _am_ saying they are not taking into account the virtual inheritance to check dtor access permission. (They do for the ctor, though.) And the matter is complicated enough that most of us more _guessed_ than _knew_ whether VC is right or wrong.
sbi
@sbi: Derived destructor calls Temp one which is private. Why guessing?
fnieto
@fnieto: I said it right, so why ask me? `:)` (Sorry for misspelling your nick, BTW. That's a hard to read font, once you're as old as I am.)
sbi
@sbi: It was a rhetorical question ;)
fnieto
@fnieto: So take my answer as rhetorical. `:^>`
sbi
A: 

Ughm, am I missing something:

$ g++ -o inherit inherit.cpp 
inherit.cpp: In constructor ‘Derived::Derived()’:
inherit.cpp:9: error: ‘Temp::~Temp()’ is private
inherit.cpp:21: error: within this context
inherit.cpp: In function ‘int main()’:
inherit.cpp:25: note: synthesized method ‘Derived::Derived()’ first required here 
inherit.cpp: In destructor ‘Derived::~Derived()’:
inherit.cpp:9: error: ‘Temp::~Temp()’ is private
inherit.cpp:21: error: within this context
inherit.cpp: In function ‘int main()’:
inherit.cpp:25: note: synthesized method ‘Derived::~Derived()’ first required here
igor
You're wrong. Note that `Temp` is a virtual base class. It is constructed, and, IMO, also destructed, by the most derived class.
sbi
Indeed - and I failed to copy it over properly too :( Anyway, gcc does give me the expected compilation error, see the edited answer above..
igor
Downvote removed -- assuming you will turn the "Ugh" into an actual answer. `:)`
sbi