 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andy Guest
|
Posted: Thu Aug 11, 2005 5:38 pm Post subject: Can I stop people deriving from my class |
|
|
The subject of this message is picked up from BS's C++ Style and
Technique FAQ at http://www.research.att.com/~bs/bs_faq2.html.
In this he describes a technique to stop a class from being derived. He
remarks "Unfortunately, that solution is not pretty. It relies on the
fact that the most derived class in a hierarchy must construct a
virtual base."
Why is the need for a virtual base?
Cheers,
Andy
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Thu Aug 11, 2005 9:02 pm Post subject: Re: Can I stop people deriving from my class |
|
|
Andy wrote:
| Quote: | The subject of this message is picked up from BS's C++ Style and
Technique FAQ at http://www.research.att.com/~bs/bs_faq2.html.
In this he describes a technique to stop a class from being derived. He
remarks "Unfortunately, that solution is not pretty. It relies on the
fact that the most derived class in a hierarchy must construct a
virtual base."
Why is the need for a virtual base?
|
Some people like having only one instance of a certain base class to be
shared between all derived classes which themselves are bases for some
other class. The shared instance needs to be declared 'virtual' when
derived from in such case.
An example follows. It may not be a great example, yet, it should show
the possible need in a virtual base class.
class Human {
bool isRightArmOk() const;
};
class Quarterback : virtual public Human {
};
class Coach : virtual public Human {
};
class CoachPlayingAsQuarterback : public Coach, Quarterback {
};
If I didn't derive 'Human' virtually, and create an instance of the latter
class, then in some function that accepted 'Coach&', the right arm of that
Coach would be hurt, in another function that checks the Quarterback part
of my playing coach, everything would be fine with the arm because the
instance of 'Human' in 'Coach' part of my playing coach and the instance
of 'Human' in 'Quarterback' part, are not the same. If I derive like I've
done here, then there is only one instance of 'Human' in my playing coach.
And if his right arm is hurt, my playing coach doesn't have another one.
Let me know if this helps.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John W. Peterson Guest
|
Posted: Fri Aug 12, 2005 9:04 am Post subject: Re: Can I stop people deriving from my class |
|
|
You've described why you want to use virtual inheritance in the case of
multiple inheritance. While true, I'm not sure this applies to the
OP's question.
Here the virtual base class is used as a technique to prevent
additional inheritance. The reason it works is stated on B.S.'s web
page: ctors for further derived classes can't access the private ctor
of the Usable_lock base class, while Usable can, since it's a friend.
Like the OP, I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andy Guest
|
Posted: Sat Aug 13, 2005 12:52 am Post subject: Re: Can I stop people deriving from my class |
|
|
Thanks for the imaginative example. However my question was about a
specific usage of virtual inheritance - I do understand what virtual
inheritance is used for normally. So I am sorry I'll have to rephrase
and elaborate my question, by borrowing material from Stroustrup's C++
Technique and Style FAQ.
To answer the question "Can I stop people from deriving from my class",
Stroustrup gives the following example:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD: D() cannot access
// Usable_lock::Usable_lock(): private member
I was wondering why virtual inheritance is needed here for Usable_lock.
That is because no class can derived from another class which itself
has Usable_lock as a base.
I want to understand the use of virtual inheritance, why we can't
simply write:
class Usable : public Usable_lock
{
...
};
Cheers,
Andy
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Sat Aug 13, 2005 1:07 am Post subject: Re: Can I stop people deriving from my class |
|
|
John wrote:
" I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?"
Rest assured it is required otherwise one can derive. Somehow the
middle class can construct the topmost class when the middle class is
instantiated, but the bottom class can't be constructed if the virtual
inheritance is used.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Martin Bonner Guest
|
Posted: Sat Aug 13, 2005 1:13 am Post subject: Re: Can I stop people deriving from my class |
|
|
John W. Peterson wrote:
| Quote: | You've described why you want to use virtual inheritance in the case of
multiple inheritance. While true, I'm not sure this applies to the
OP's question.
Here the virtual base class is used as a technique to prevent
additional inheritance. The reason it works is stated on B.S.'s web
page: ctors for further derived classes can't access the private ctor
of the Usable_lock base class, while Usable can, since it's a friend.
Like the OP, I'm not sure about the significance of the virtual
inheritance here either
...it seems normal public inheritance would
achieve the same effect?
|
No it wouldn't. Because Usable derives normally from Usable_lock, if
somebody creates UnUsable which derives from Usable, then the UnUsable
constructor is required to construct Usable_lock. The problem is that
UnUsable /can't/ call the constructor because UnUsable isn't a friend.
If Usable were to use normal derivation from Usable_lock, then Usable's
constructor would construct Usable_lock, and a derived class would just
construct Usable without problem.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Khoguan Phuann Guest
|
Posted: Sat Aug 13, 2005 1:15 am Post subject: Re: Can I stop people deriving from my class |
|
|
John W. Peterson wrote:
| Quote: | Here the virtual base class is used as a technique to prevent
additional inheritance. The reason it works is stated on B.S.'s web
page: ctors for further derived classes can't access the private ctor
of the Usable_lock base class, while Usable can, since it's a friend.
Like the OP, I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?
|
12.6.2/6 of the Standard:
"All sub-objects representing virtual base classes are initialized
by the constructor of the most derived class. If the constructor
of the most derived class does not specify a mem-initializer for
a virtual base class V, then V's default constructor is called to
initialize the virtual base class subobject. If V does not have
an accessible default constructor, the initialization is ill-formed.
A mem-initializer naming a virtual base class shall be ignored
during execution of the constructor of any class that is not the
most derived class."[example elided]
HTH,
Khoguan Phuann
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mike Capp Guest
|
Posted: Sat Aug 13, 2005 1:18 am Post subject: Re: Can I stop people deriving from my class |
|
|
| Quote: | Like the OP, I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?
|
No. The key point in Bjarne's example is that the most derived class
initializes a virtual base. DD is not a friend of Usable_lock, hence
cannot see Usable_lock's private constructor, hence cannot call it.
If non-virtual inheritance had been used, DD wouldn't need to call
Usable_lock's ctor. It would only need to call Usable's ctor (which it
can), and Usable's ctor would then initialize Usable_lock.
cheers
Mike
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hyman Rosen Guest
|
Posted: Sat Aug 13, 2005 1:28 am Post subject: Re: Can I stop people deriving from my class |
|
|
John W. Peterson wrote:
| Quote: | ctors for further derived classes can't access the private ctor
of the Usable_lock base class, while Usable can, since it's a friend.
Like the OP, I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?
|
When a class is inherited virtually, its constructor must be invoked
by the most derived class.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Sat Aug 13, 2005 1:32 am Post subject: Re: Can I stop people deriving from my class |
|
|
John W. Peterson wrote:
| Quote: | You've described why you want to use virtual inheritance in the case of
multiple inheritance. While true, I'm not sure this applies to the
OP's question.
[...]
|
Yes, sorry, didn't understand what the OP was asking about.
The virtual bases are to be initialised in the most derived class. If
you inherit Usable_lock regularly, then the derived class DD won't have
to try to access Usable_lock's constructor. If it is derived virtually
in Usable, then DD needs to have access to Usable_lock's c-tor (which
it doesn't because they are private).
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
msalters Guest
|
Posted: Sat Aug 13, 2005 1:37 am Post subject: Re: Can I stop people deriving from my class |
|
|
John W. Peterson schreef:
| Quote: | You've described why you want to use virtual inheritance in the case of
multiple inheritance. While true, I'm not sure this applies to the
OP's question.
Here the virtual base class is used as a technique to prevent
additional inheritance. The reason it works is stated on B.S.'s web
page: ctors for further derived classes can't access the private ctor
of the Usable_lock base class, while Usable can, since it's a friend.
Like the OP, I'm not sure about the significance of the virtual
inheritance here either...it seems normal public inheritance would
achieve the same effect?
|
No, with normal public inheritance the most derived class doesn't call
the deepest base class ctor directly.
I.e. with A<-B<-C and virtual A, C::C calls A::A. With a non virtual
base A, C::C calls only B::B. A::A is called from B::B, but B is a
friend.
Your explanation was OK, though.
HTH,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|