Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > privatising public member functions in derived classes.

Reply
Thread Tools

privatising public member functions in derived classes.

 
 
Firkraag
Guest
Posts: n/a
 
      11-21-2007
Hello

#include <iostream>
using std::cout;

struct A {
~virtual A(){}
virtual void foo(){ cout << "aaa\n"; }
};

struct B : A {
private:
virtual void foo(){ cout << "bbb\n"; }
};

void bar(A& ab)
{
ab.foo();
}


int main()
{
A a;
B b;
bar(b)
}

The above code works properly. As far as I know LSP is not being
violated here. So why FAQ lite says this:
http://www.parashift.com/c++-faq-lit....html#faq-21.1
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      11-21-2007
Firkraag wrote:
> #include <iostream>
> using std::cout;
>
> struct A {
> ~virtual A(){}
> virtual void foo(){ cout << "aaa\n"; }
> };
>
> struct B : A {
> private:
> virtual void foo(){ cout << "bbb\n"; }
> };
>
> void bar(A& ab)
> {
> ab.foo();
> }
>
>
> int main()
> {
> A a;
> B b;
> bar(b)
> }
>
> The above code works properly. As far as I know LSP is not being
> violated here. So why FAQ lite says this:
> http://www.parashift.com/c++-faq-lit....html#faq-21.1


Compile this version of 'main' instead:

template<class T> void callFoo(T &t)
{
t.foo();
}

int main()
{
B b;
callFoo(b);
}

Now, the "duck typing" doesn't work, does it? LSP or not, what is
the point of hiding 'foo' in 'B'? If you didn't intend to call the
'foo' member directly, you ought to make it private and keep it
private:

struct A {
private:
virtual void foo() { cout << "aaa\n"; }
public:
void doFoo() { foo(); }
};

struct B : A {
private:
virtual void foo() { cout << "bbb\n"; }
};

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
werasm
Guest
Posts: n/a
 
      11-21-2007
On Nov 21, 5:12 am, "Victor Bazarov" <(E-Mail Removed)> wrote:

> Now, the "duck typing" doesn't work, does it? LSP or not, what is
> the point of hiding 'foo' in 'B'? If you didn't intend to call the
> 'foo' member directly, you ought to make it private and keep it
> private:
>
> struct A {
> private:
> virtual void foo() { cout << "aaa\n"; }
> public:
> void doFoo() { foo(); }
> };
>
> struct B : A {
> private:
> virtual void foo() { cout << "bbb\n"; }
> };


To me this also seems a little pointless. If I want to convey
to clientA that he may only call foo (or doFoo, for that
matter), nothing stops client B from calling doFoo().

What you are showing here above allows doFoo to dictate
the order of the calling (template method) if there is
an order, but it does not help with indicating which
client is supposed to use the applicable interface.

This however does:

class A
{
friend class ClientOfA;
virtual void foo() = 0;
//...
};

or...

class A
{
friend class ClientOfA;
void doFoo(){ /*..call foo etc...*/ }
virtual void foo() = 0;
};

class B{}; //All above private.
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      11-21-2007
werasm wrote:
> On Nov 21, 5:12 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
>
>> Now, the "duck typing" doesn't work, does it? LSP or not, what is
>> the point of hiding 'foo' in 'B'? If you didn't intend to call the
>> 'foo' member directly, you ought to make it private and keep it
>> private:
>>
>> struct A {
>> private:
>> virtual void foo() { cout << "aaa\n"; }
>> public:
>> void doFoo() { foo(); }
>> };
>>
>> struct B : A {
>> private:
>> virtual void foo() { cout << "bbb\n"; }
>> };

>
> To me this also seems a little pointless. If I want to convey
> to clientA that he may only call foo (or doFoo, for that
> matter), nothing stops client B from calling doFoo().


But that's the whole point! The client of A or B or any other
derived classes will have to always call doFoo() instead of
'foo' (which can have different behaviour due to static or
dynamic binding, IOW when calling through a pointer or directly
for an object).

> What you are showing here above allows doFoo to dictate
> the order of the calling (template method)


What template method? What are you talking about?

> if there is
> an order, but it does not help with indicating which
> client is supposed to use the applicable interface.


Huh?

>
> This however does:


Does what, exactly?

>
> class A
> {
> friend class ClientOfA;
> virtual void foo() = 0;
> //...
> };
>
> or...
>
> class A
> {
> friend class ClientOfA;
> void doFoo(){ /*..call foo etc...*/ }
> virtual void foo() = 0;
> };
>
> class B{}; //All above private.


The idiom of having all virtual interface private (pure or not)
and having a public interface that just forwards the calls to the
virtual function, is well known and commonly accepted in the
industry. The main advantage is that there is a single point of
call for all classes in the hierarchy, where you can put your
pre- and post-conditions, and the virtual interface is never
exposed for an occasional non-virtual call (where you can't tell
just by looking which of the functions is going to be called).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
werasm
Guest
Posts: n/a
 
      11-21-2007
On Nov 21, 3:21 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> werasm wrote:


> > To me this also seems a little pointless. If I want to convey
> > to clientA that he may only call foo (or doFoo, for that
> > matter), nothing stops client B from calling doFoo().

>
> But that's the whole point! The client of A or B or any other
> derived classes will have to always call doFoo() instead of
> 'foo' (which can have different behaviour due to static or
> dynamic binding, IOW when calling through a pointer or directly
> for an object).
>
> > What you are showing here above allows doFoo to dictate
> > the order of the calling (template method)

>
> What template method? What are you talking about?


http://en.wikipedia.org/wiki/Template_method

More or less exactly what you are describing, but not
good enough. The Template method pattern (sorry, I
assumed you were familiar with the name) dictates
the order of behaviour (Pre-conditions, Post-conditions
etc.) iff there is an order (in the case of the example
there was none).

> > if there is
> > an order, but it does not help with indicating which
> > client is supposed to use the applicable interface.


Client A wants to use Service A, and Client A dictates
what it requires in terms of service. In the case
of "Template Method" (what you have described) the
service exists prior to the client using it (mostly),
whereas often it works the other way around (in which
case the pre/post conditions live in the calling code
and not in the called code). The client often may
no too little of the implementation to dicate anything
apart from knowing what service it wants (which brings
you back to pure virtual).

> Huh?
>
> > This however does:

>
> Does what, exactly?


This (or the example) allows the interface to be
used only by the client that required it and gives
the interface a single responsibility (in terms of
one client only). For me this solves the problem
of the OP better (in this particular case where
doFoo does not provide any additional encapsulation
as no pre/post conditions exist as the service
implementation is unknown, and if they did exist,
they could be performed in the calling code too).

> The idiom of having all virtual interface private (pure or not)
> and having a public interface that just forwards the calls to the
> virtual function, is well known and commonly accepted in the
> industry.


Yes, I realize this (Its called "template method", not?, but this
to me was not what the OP was looking for (perhaps he was, but
I saw something else in his request).

> The main advantage is that there is a single point of
> call for all classes in the hierarchy, where you can put your
> pre- and post-conditions, and the virtual interface is never
> exposed for an occasional non-virtual call (where you can't tell
> just by looking which of the functions is going to be called).


I realize this. When I said "no point" I meant with respect to
the case he specified (where pre/post conditions don't
necessarily exist or are not known). Sometimes interfaces are merely
used (in OOP) to convey intent and specify/dictate responsibility.
In these cases the idiom you make mention of is lacking, whilst
my example makes this clear.
 
Reply With Quote
 
Ron Natalie
Guest
Posts: n/a
 
      11-23-2007
Firkraag wrote:

> }
>
> The above code works properly. As far as I know LSP is not being
> violated here. So why FAQ lite says this:
> http://www.parashift.com/c++-faq-lit....html#faq-21.1


First the name is looked up.
Then overloads for the found name are considered.
Then the access for the best overload is considered.

THEN, if the function is virtual, the final overrider is
invoked.


As with most everything else in C++, the thing that matters
is the static declaration at the pointer of the call.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
privatising public member functions in derived classes Firkraag C++ 0 11-21-2007 03:16 AM
microsoft.public.certification, microsoft.public.cert.exam.mcsa, microsoft.public.cert.exam.mcad, microsoft.public.cert.exam.mcse, microsoft.public.cert.exam.mcsd loyola MCSE 4 11-15-2006 02:40 AM
microsoft.public.certification, microsoft.public.cert.exam.mcsa, microsoft.public.cert.exam.mcad, microsoft.public.cert.exam.mcse, microsoft.public.cert.exam.mcsd loyola Microsoft Certification 3 11-14-2006 05:18 PM
microsoft.public.certification, microsoft.public.cert.exam.mcsa, microsoft.public.cert.exam.mcad, microsoft.public.cert.exam.mcse, microsoft.public.cert.exam.mcsd realexxams@yahoo.com Microsoft Certification 0 05-10-2006 02:35 PM
microsoft.public.dotnet.faqs,microsoft.public.dotnet.framework,microsoft.public.dotnet.framework.windowsforms,microsoft.public.dotnet.general,microsoft.public.dotnet.languages.vb Charles A. Lackman ASP .Net 1 12-08-2004 07:08 PM



Advertisments