Topic: how to override safe (c++ design problem)
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 22 Jun 1994 20:44:16 GMT Raw View
In article <10405@bredex.de> nico@bredex.de (Nico Josuttis) writes:
>IMHO here is a design problem due to private inheritance in C++:
>
>I wonder how i can override a member function in a safe way.
>What i mean is:
> If i override a member function from a base class, the base class
> implementation may be called using the operator ::
> Example:
> class B {
> public:
> void foo ();
> };
Did you mean foo() to be virtual?
> class D : public B {
> public:
> void foo (); // overrides B::foo() (which would be wrong)
> };
>
> OK, to be safe, i have to prevent this, denying calling B::foo() for d.
Easy.
class B { virtual void _foo(); public: void foo(); };
class D : public virtual A { void _foo(); };
The only way the public can call the function is by
the NON-virtual B::foo() which always calls the
final overrider virtual D::_foo(). Not that it should matter.
If calling D::_foo() gives a different answer to calling
B::_foo() your design is broken. D::_foo() MUST give the
same answers as B::_foo(), the only difference is its allowed
to be faster (unless B::_foo() isnt implemented in which case
the condition is satisfied vacuously because B::_foo() then
isnt callable).
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: nico@bredex.de (Nico Josuttis)
Date: 13 Jun 94 12:26:36 GMT Raw View
IMHO here is a design problem due to private inheritance in C++:
I wonder how i can override a member function in a safe way.
What i mean is:
If i override a member function from a base class, the base class
implementation may be called using the operator ::
Example:
class B {
public:
void foo ();
fiend ostream& operator<< (ostream&, const B&);
...
};
class D : public B {
public:
void foo (); // overrides B::foo() (which would be wrong)
...
};
main()
{
D d;
cout << d; // fine, due to inheritance
d.B::foo(); // calls wrong function from base class
}
OK, to be safe, i have to prevent this, denying calling B::foo() for d.
Example:
class B {
public:
void foo ();
fiend ostream& operator<< (ostream&, const B&);
...
};
class D : protected B {
public:
void foo (); // overrides B::foo() (which would be wrong)
...
};
main()
{
D d;
d.B::foo(); // ERROR, fine, but...
cout << d; // also ERROR oops !!
}
As you see, now i can't use d as B anymore, cause private inheritance is
no inheritance (inheritance only for the implementation).
But in general i want to use polymorphism and i want to use d as B.
So what can I do to solve that problem?
Any meanings/ideas ??
Oh: due to the C++ news overhead:
- sorry if this has been discussed before
- please answer me also directly
Thanks in advance
-----
Nico address: BREDEX GmbH
email: nico@bredex.de Nicolai Josuttis
Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
Author: pjl@graceland.att.com (Paul J. Lucas)
Date: Tue, 14 Jun 1994 22:57:46 GMT Raw View
In <10405@bredex.de> nico@bredex.de (Nico Josuttis) writes:
>IMHO here is a design problem due to private inheritance in C++:
>I wonder how i can override a member function in a safe way.
>What i mean is:
> If i override a member function from a base class, the base class
> implementation may be called using the operator ::
> Example:
> class B {
> public:
> void foo ();
> fiend ostream& operator<< (ostream&, const B&);
> ...
> };
> class D : public B {
> public:
> void foo (); // overrides B::foo() (which would be wrong)
> ...
> };
> main()
> {
> D d;
> cout << d; // fine, due to inheritance
> d.B::foo(); // calls wrong function from base class
> }
>
> OK, to be safe, i have to prevent this, denying calling B::foo() for d.
> Example:
> class B {
> public:
> void foo ();
> fiend ostream& operator<< (ostream&, const B&);
> ...
> };
> class D : protected B {
> public:
> void foo (); // overrides B::foo() (which would be wrong)
> ...
> };
> main()
> {
> D d;
> d.B::foo(); // ERROR, fine, but...
> cout << d; // also ERROR oops !!
> }
>As you see, now i can't use d as B anymore, cause private inheritance is
>no inheritance (inheritance only for the implementation).
>But in general i want to use polymorphism and i want to use d as B.
>
>So what can I do to solve that problem?
>Any meanings/ideas ??
Don't worry about it. If a user explicity calls B::foo(), s/he
deserves what she gets and should understand what s/he is doing
to get it.
--
- Paul J. Lucas
AT&T Bell Laboratories
Naperville, IL
Author: davida@london.sbi.com (David Artus)
Date: 15 Jun 1994 12:38:36 GMT Raw View
Nico Josuttis (nico@bredex.de) wrote:
: IMHO here is a design problem due to private inheritance in C++:
: I wonder how i can override a member function in a safe way.
: What i mean is:
: If i override a member function from a base class, the base class
: implementation may be called using the operator ::
: Example:
: class B {
: public:
: void foo ();
: fiend ostream& operator<< (ostream&, const B&);
: ...
: };
: class D : public B {
: public:
: void foo (); // overrides B::foo() (which would be wrong)
: ...
: };
: main()
: {
: D d;
: cout << d; // fine, due to inheritance
: d.B::foo(); // calls wrong function from base class
: }
In my opinion you are trying to stop people shooting themselves in the
foot. There are many ways of hurting yourself in C++, this one is
comparatively easy to avoid. Someone is unlikely to go to the trouble of
writing 'd.B::foo()' instead of 'd.foo()', and not realise what
they are doing. I think that C++ makes very few concessions to hand-holding
in general; I imagine that was a deliberate design decision. If you provide
a B class and someone deliberately circumvents the encapsualtion in this
way then they deserve everything they get. Could the language be extended
with some syntax to prevent the thing that worries you? Possibly, but
we [by we I of corse mean me and all right thinking people ;-) ]
don't at present need more langauge extensions. If you care passionately
then amend a copy of the gnu compiler as you see fit, get the amended
version used extensively by you and other folks (prefereably including
some argumentative language lawyer types) and then you might be in a position
to propose a well defined language extension.