design problem with inheritance

A

alessio211734

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
virtual void fly(){......}
void display();

}

class FakeDuck: public duck()
{
void fly(){ override to nothing...}

}

if I have a FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.


book propose the pattern strategy and to extern the fly behavior as a
external class

class FlyBehavior
{
virtual void fly()=0;
}

class NoFly: public FlyBehavior
{
virtual void fly(){ printf("can't fly")};


and the class duck became

class duck
{
FlyBehavior * bhv;
void performFly(){ bhv->fly(); }
}

I have doubts about the design proposed because book says
encapsulating the algorithms in a class hierarchy and make them
interchangeable.
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??
What's the best solutions?


Thanks in advance.

Ale.
 
P

Paul

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
    virtual void fly(){......}
    void display();

}

class FakeDuck: public duck()
{
    void fly(){ override to nothing...}

}

if I have a  FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

book propose the pattern strategy and to extern the fly behavior as a
external class

class FlyBehavior
{
     virtual void fly()=0;

}

class NoFly: public FlyBehavior
{
    virtual void fly(){ printf("can't fly")};

and the class duck became

class duck
{
    FlyBehavior * bhv;
    void performFly(){ bhv->fly(); }

}

I have doubts about the design proposed because book says
encapsulating the algorithms in a class hierarchy and make them
interchangeable.
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??
What's the best solutions?
Hi I see a problem with your ..
void performFly(){ bhv->fly();

bhv needs to be initialed to point to either a Fly or NoFly object. I
did a little test program with an example of initialisng a default
Constructor to NoFly and a Constructor that takes a bool value for fly
or nofly.

class FlyBehav{
public:
virtual void Fly()=0;
};

class NoFly: public FlyBehav{
public:
void Fly(){std::cout<<"Cannot Fly\n";}
};
class CanFly: public FlyBehav{
public:
void Fly(){std::cout<<"Flying across the sky\n";}
};

class Duck{
FlyBehav* ptrFly;
bool can_fly;
public:
Duck():can_fly(0),ptrFly(new NoFly){}
Duck(bool b):can_fly(b){
if(b)ptrFly=new CanFly;
else ptrFly=new NoFly;
}
void PerformFly(){ptrFly->Fly();}
~Duck(){delete ptrFly;}
};

int main() {
Duck flying_duck(1);
d.PerformFly();
}


HTH
 
A

alessio211734

ok thanks for correction, I put a incomplete code but my problem is
another, how with this design I can access to private data of class
Duck
when implements the Fly method?


class NoFly: public FlyBehav{
public:
void Fly(){std::cout<<"Cannot Fly\n";}
};

class CanFly: public FlyBehav{
public:
void Fly()
{
// how get Duck private data???
std::cout<<"Flying across the sky\n";
}

};

if the Fly() method of CanFly or NoFly needs to privata data of the
class Duck how can do it with this design?

Maybe I could pass a pointer to base class Duck but so I can access
only to public member of Duck. I would like access to Duck private
data.


class FlyBehav{
public:
FlyBehav(Duck * _ownClass)
{
ownClass=_ownClass;
}
virtual void Fly()=0;
};

class CanFly: public FlyBehav{
public:
CanFly(Duck * ownClass)
{

}
void Fly()
{
std::cout<<"Flying across the sky\n";}
ownClass->DuckPublicMethod();
// no ways to acess to Duck private data or private
method!!!
}
};
 
P

Paul

ok thanks for correction, I put a incomplete code but my problem is
another, how with this design I can access to private data of class
Duck
when implements the Fly method?

class NoFly: public FlyBehav{
public:
        void Fly(){std::cout<<"Cannot Fly\n";}

};

class CanFly: public FlyBehav{
public:
        void Fly()
        {
            // how get Duck private data???
            std::cout<<"Flying across the sky\n";
        }

};

if the Fly() method of CanFly or NoFly needs to privata data of the
class Duck how can do it with this design?

Maybe I could pass a pointer to base class Duck but so I can access
only to public member of Duck. I would like access to Duck private
data.

class FlyBehav{
public:
        FlyBehav(Duck * _ownClass)
        {
            ownClass=_ownClass;
        }
        virtual void Fly()=0;

};

class CanFly: public FlyBehav{
public:
        CanFly(Duck * ownClass)
        {

        }
        void Fly()
        {
             std::cout<<"Flying across the sky\n";}
             ownClass->DuckPublicMethod();
             // no ways to acess to Duck private data or private
method!!!
        }



};- Hide quoted text -

- Show quoted text -

Make it a friend class.

class Duck{
friend class CanFly;
.....
}

This gives CanFly access to Ducks private members ^_^.
I don't know how it works with inheritance OTTOMH but maybe its
possible to make FlyBehav a friend and therefore allow its derived
access too. Just a thought but I'd need to go read up on it to get all
the details.

And if you derived duck to e.g: fakeduck, again I don't know all the
detialed rules of friend classes when inheritance gets a bit
complicated. WOuld need to refer to a manual.

HTH
 
V

Victor Bazarov

ok thanks for correction, I put a incomplete code but my problem is
another, how with this design I can access to private data of class
Duck
when implements the Fly method?

First off, what correction? If you post a reply, consider quoting or at
least commenting on what you're referring to.

Second, nobody but Duck (or its friends) can access private members of
Duck. If you need to get to those from derived classes, provide an
interface (possibly 'protected' to limit access to derived classes only)
in the Duck itself.
class NoFly: public FlyBehav{
public:
void Fly(){std::cout<<"Cannot Fly\n";}
};

class CanFly: public FlyBehav{
public:
void Fly()
{
// how get Duck private data???
std::cout<<"Flying across the sky\n";
}

};

if the Fly() method of CanFly or NoFly needs to privata data of the
class Duck how can do it with this design?

Maybe I could pass a pointer to base class Duck but so I can access
only to public member of Duck. I would like access to Duck private
data.

That's just a wrong premise. Private data are private for a very simple
reason: nobody should have access to them, not even derived classes. If
Duck needs to grant access to some data to the derived classes for
whatever reason, make the members 'protected'.
class FlyBehav{
public:
FlyBehav(Duck * _ownClass)
{
ownClass=_ownClass;
}
virtual void Fly()=0;
};

class CanFly: public FlyBehav{
public:
CanFly(Duck * ownClass)
{

}
void Fly()
{
std::cout<<"Flying across the sky\n";}
ownClass->DuckPublicMethod();
// no ways to acess to Duck private data or private
method!!!
}
};

V
 
J

Juha Nieminen

Paul said:
Hi I see a problem with your ..
void performFly(){ bhv->fly();

bhv needs to be initialed to point to either a Fly or NoFly object. I
did a little test program with an example of initialisng a default
Constructor to NoFly and a Constructor that takes a bool value for fly
or nofly.

Your ability to always completely miss the point never ceases to
amaze me.

You are exactly the type of person that if someone told you
that one morning when he was driving to work his car broke and he
returned home to call a garage, only to find his wife cheating on him
with the neighbor and asked you what to do, you would start explaining
him what to check in the car to see what's broken.
 
P

Paul

  Your ability to always completely miss the point never ceases to
amaze me.

  You are exactly the type of person that if someone told you
that one morning when he was driving to work his car broke and he
returned home to call a garage, only to find his wife cheating on him
with the neighbor and asked you what to do, you would start explaining
him what to check in the car to see what's broken.

Ha ha :)
 
A

alessio211734

First off, what correction?  If you post a reply, consider quoting or at
least commenting on what you're referring to.

Second, nobody but Duck (or its friends) can access private members of
Duck.  If you need to get to those from derived classes, provide an
interface (possibly 'protected' to limit access to derived classes only)
in the Duck itself.

Ok thanks, you explain me how c++ work with friend and protected
keyword but I ask you how adjust my design.
In the initial design I have one class Duck and some derived class
StandardDuck and FakeDuck both derived from Duck class.
the class FakeDuck override the fly method and make it empty. I think
this is a bad design.
Book proposed to use a pattern strategy and use FlyBehav interface to
handle behavior as fly and nofly

class FlyBehav{
public:
virtual void Fly()=0;
};

class NoFly: public FlyBehav{
public:
void Fly(){std::cout<<"Cannot Fly\n";}
};

class CanFly: public FlyBehav{
public:
void Fly(){std::cout<<"Flying across the sky\n";}
};

I think this pattern is right if method Fly no needs private data of
Duck class as in this example.
but in a real case I think that the Fly method needs to data about
Duck class. And so in this case what's the best design to solve my
problem?
I would like avoid to create a class FakeDuck with a empty method. I
think Strategy it's not right.




A.
 
V

Victor Bazarov

Ok thanks, you explain me how c++ work with friend and protected
keyword but I ask you how adjust my design.

How do you adjust a radio to give you coffee? You can't. A coffee
machine is not going to play a tune, unless it is *also* a radio. If
it's just a coffee machine, it cannot be "adjusted" to become a radio.
In the initial design I have one class Duck and some derived class
StandardDuck and FakeDuck both derived from Duck class.
So?

the class FakeDuck override the fly method and make it empty. I think
this is a bad design.

You didn't explain why it's bad.

What's a Duck? Something that has the 'fly' method. By your design,
since you derived 'FakeDuck' from 'Duck', publicly, you said,
essentially, that a 'FakeDuck' *is-a* 'Duck', which means 'FakeDuck'
*shall have* a 'fly' method. How is that "bad", if that's your design?
If 'FakeDuck' is NOT a 'Duck', don't derive it from 'Duck'.
Book proposed to use a pattern strategy and use FlyBehav interface to
handle behavior as fly and nofly

class FlyBehav{
public:
virtual void Fly()=0;
};

class NoFly: public FlyBehav{
public:
void Fly(){std::cout<<"Cannot Fly\n";}
};

class CanFly: public FlyBehav{
public:
void Fly(){std::cout<<"Flying across the sky\n";}
};

Rename 'FlyBehav' to 'Duck', 'CanFly' to 'StandardDuck', and 'NoFly' to
'FakeDuck', and you get the same hierarchy as before.
I think this pattern is right if method Fly no needs private data of
Duck class as in this example.

I don't get it.
but in a real case I think that the Fly method needs to data about
Duck class. And so in this case what's the best design to solve my
problem?

I don't know. WHAT PROBLEM?
I would like avoid to create a class FakeDuck with a empty method. I
think Strategy it's not right.

So, don't use the Strategy.

Perhaps you need to start with the PROBLEM you're trying to solve
instead of the NON-WORKING solutions you have come up with.

V
 
P

Paul N

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
virtual void fly(){......}
void display();

}

class FakeDuck: public duck()
{
void fly(){ override to nothing...}

}

if I have a FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

book propose the pattern strategy and to extern the fly behavior as a
external class

class FlyBehavior
{
virtual void fly()=0;

}

class NoFly: public FlyBehavior
{
virtual void fly(){ printf("can't fly")};

and the class duck became

class duck
{
FlyBehavior * bhv;
void performFly(){ bhv->fly(); }

}

I have doubts about the design proposed because book says
encapsulating the algorithms in a class hierarchy and make them
interchangeable.
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??
What's the best solutions?

I'm not an expert, but it seems to me that the proposed solution is
trying to provide a "library" of different fly behaviours, with each
type of duck able to choose any of them, presumably in a way that
doesn't fit in well with the duck hierarchy. So if you want the fly
behaviour to depend on details of the particular duck you are probably
using the wrong solution.

Of course, if the different fly behaviours get built out of standard
blocks, you could define virtual functions to do these, perhaps
something like:


class Fly: public FlyBehavior
{
virtual void fly(duck *d) { d -> FlapWings(); } };

class duck
{
....
virtual void FlapWings(); }

Hope that helps.
Paul.
 
J

Joshua Maurice

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
    virtual void fly(){......}
    void display();

}

class FakeDuck: public duck()
{
    void fly(){ override to nothing...}

}

if I have a  FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

book propose the pattern strategy and to extern the fly behavior as a
external class

class FlyBehavior
{
     virtual void fly()=0;

}

class NoFly: public FlyBehavior
{
    virtual void fly(){ printf("can't fly")};

and the class duck became

class duck
{
    FlyBehavior * bhv;
    void performFly(){ bhv->fly(); }

}

I have doubts about the design proposed because book says
encapsulating the algorithms in a class hierarchy and make them
interchangeable.
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??
What's the best solutions?

Thanks in advance.

See the FAQ.

http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.6

There is no single right answer. A good answer depends heavily upon
your particular problem, which you have not explained at all.
 
A

alessio211734

I'm not an expert, but it seems to me that the proposed solution is
trying to provide a "library" of different fly behaviours, with each
type of duck able to choose any of them, presumably in a way that
doesn't fit in well with the duck hierarchy. So if you want the fly
behaviour to depend on details of the particular duck you are probably
using the wrong solution.

Of course, if the different fly behaviours get built out of standard
blocks, you could define virtual functions to do these, perhaps
something like:

class Fly: public FlyBehavior
{
virtual void fly(duck *d) { d -> FlapWings(); } };

class duck
{
...
virtual void FlapWings(); }

Hope that helps.
Paul.

Thanks, this is the first solution about this thread but if FlapWings
is a private method I have no way to access to it?!?
 
P

Paul

Thanks, this is the first solution about this thread but if FlapWings
is a private method I have no way to access to it?!?- Hide quoted text -
You would need to make flapwings public.
 
A

alessio211734

You would need to make flapwings public.
Yes this is the lack I see with this design, I should do public
methods in the class Duck to access them from a external class.
 
M

Michael DOUBEZ

Yes this is the lack I see with this design, I should do public
methods in the class Duck to access them from a external class.

There is an alternative, make FlyBehavior a friend of Duck and code
protected class member function in FlyBehavior for accessing duck's
private members. That way, only class inheriting FlyBehavior can
access those members.

If you are afraid of cluttering the interface, you can also declare a
protected nested class.
Example:
#include <iostream>

class duck;

class FlyBehavior
{
public: virtual void fly( duck* d) = 0;

protected:
friend class duck; // duck can declare DuckFlyBehavior a friend;
class DuckFlyBehavior;
};


class duck
{
public:
duck(FlyBehavior& f):_fb(&f){}

void fly(){ _fb->fly(this); }

protected:
friend class FlyBehavior::DuckFlyBehavior; // DuckFlyBehavior can
call FlapWings
void FlapWings(){ std::cout<<"flap flap\n"; }

private:
FlyBehavior* _fb;
};


struct FlyBehavior::DuckFlyBehavior
{
// break encapsulation of duck
static void FlapWings(duck* d){
d->FlapWings();
}
};

class Fly: public FlyBehavior
{
public:
virtual void fly(duck *d) { DuckFlyBehavior::FlapWings(d); }
};

int main()
{
Fly fly;
duck donald(fly);

donald.fly();
}
 
J

James Kanze

I am reading a design pattern book.
the example is a class duck that a method fly
class duck
{
virtual void fly(){......}
void display();
}
class FakeDuck: public duck()
{
void fly(){ override to nothing...}
}
if I have a FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

If there are many such subclasses, then perhaps fly shouldn't be
a function of the base interface. If there are many such
subclasses, however, Duck probably isn't a very good name for
the base class. It's very, very exceptional that ducks can't
fly.

More generally, however, the problem might occur for Animal;
some animals can fly, but most can't. The solution in such
cases is generally to extend the interface:

class Animal
{
// No function fly.
};

class FlyingAnimal : public virtual Animal
{
virtual void fly() = 0;
};

Animals which can fly implement FlyingAnimal; animals which
can't implement Animal. Client code which needs to make the
animal fly will first dynamic_cast the Animal* to FlyingAnimal*,
and take whatever actions are appropriate if the dynamic_cast
fails.

(Note too that the inheritance is virtual. This should almost
always be the case when extending an interface: one can easily
imagine a SwimmingAnimal, a WalkingAnimal, etc., and concrete
animals which implement more than one of these.)
book propose the pattern strategy and to extern the fly
behavior as a
class FlyBehavior
{
virtual void fly()=0;
}

I think you're misunderstanding the book. The strategy pattern
is about implementation, not interface.
class NoFly: public FlyBehavior
{
virtual void fly(){ printf("can't fly")};
and the class duck became
class duck
{
FlyBehavior * bhv;
void performFly(){ bhv->fly(); }
}
I have doubts about the design proposed because book says
encapsulating the algorithms in a class hierarchy and make them
interchangeable.
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??

Then perhaps the strategy pattern is not the best solution. The
big advantage of the strategy pattern is that it allows changing
the strategy dynamically. If you don't need this, you can use
the template method pattern, or mixins---a certain type of wing
supports flying, and an animal which has this type of wing and
can fly inherits (privately, since this is implementation) from
this type of wing; the "member data" to which the function needs
access is a class which implements the actual function.

But it depends. In such cases, it's not rare that in certain
cases, the concrete strategy is a member (usually private) of
the concrete class. In this case, the concrete strategy has
can have access to the member data.
 
N

Noah Roberts

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
    virtual void fly(){......}
    void display();

}

class FakeDuck: public duck()
{
    void fly(){ override to nothing...}

}

if I have a  FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

book propose the pattern strategy and to extern the fly behavior as a
external class

It's a poor example and a poor reason to use a strategy. You use
strategy patterns when it makes sense for the concept to have
different behaviors in a certain area. For example, the sort-like
routines in the standard library all allow you to override their
comparison routine. This is because though you might compare
differently among various types or situations, you will always make
some sort of comparison or you wouldn't bother sorting. It makes zero
sense to call sort with a noop comparator.

What this book has done is show how to work around a questionable
interface design in a questionable manner. I see no benefit to using
the strategy over providing a noop stub in the subclass. In fact, of
bad solutions I think the latter is probably the better. The real
solution here is to realize that since not all ducks fly, pretending
that they do is a bad design choice. The fly functionality should be
an aspect only of those kinds of ducks that DO fly. Thus you have
something more like so:

struct duck
{
};

struct flying_duck : duck
{
virtual void fly() = 0;
};

struct fake_duck : duck {};

Alternatively one might propose completely different design choices
since flight ability is a static property of some kinds of birds. One
might use multiple inheritence to provide a can_fly interface that
some animal derivatives can advertize...this allows one to use the
same flight interface for bats as one does for birds.

If the function overload here was "move" or "motivate" or something
like that, one might use the strategy pattern to provide various
alternatives such as fly, walk, slither, etc... For the case they've
shown here though I see it as utterly inappropriate.
 
N

Noah Roberts

I am reading a design pattern book.

the example is a class duck that a method fly

class duck
{
    virtual void fly(){......}
    void display();

}

class FakeDuck: public duck()
{
    void fly(){ override to nothing...}

}

if I have a  FakeDuck class it's need to override the fly method to
nothing because a FakeDuck can't fly.
And so on for every subclass of duck that have no fly feature.

book propose the pattern strategy and to extern the fly behavior as a
external class

Actually, I thought of a better example. I see the strategy pattern
as a way to replace behavior dynamically. There is a static version
of the strategy pattern in C++ using templates, but as far as "design
patterns" goes I see this as primarily a runtime alteration.

Consider various animals you might design classes for. Some animals
fly, some walk, some run, some slither, etc... Some can do more than
one thing. You could design these characteristics in a variety of
ways but they'll remain primarily static choices, things that do not
change based on the state of the program.

What if though you wanted to write an escapePredation function?
Consider then what ducks might do... Depending on the situation they
might run into a lake and swim away. Other times they may fly to the
same lake and swim. They might simply fly as far away as they can.
Other times they run away into the woods or something, though more
often toward some body of water. If its a mother duck it might not
escape at all but turn and fight....or at least flap around violently.

All of these are situational concerns that are based on the
surroundings of the animal and its current state of mind. How
frightened is it, etc... Some of these strategies are shared by other
animals or birds. For example, most birds will use the fly strategy
to flee in some situations. Your strategy here then becomes something
that operates on animals and the interfaces you've set up, and this
strategy could be returned by your duck class if you call a
"getEscapeStrategy()" function.
 
R

Rui Maciel

alessio211734 said:
But ok if I need the private data about duck class to implement the
fly method of NoFly class how can do it??
What's the best solutions?

You should pass class duck's private data to the methods defined in class
FlyBehavior as parameters. So, taking your example:

<code>
class FlyBehavior
{
virtual void fly(DuckData &)=0;
}


class NoFly
: public FlyBehavior
{
virtual void fly(DuckData &){ std::cout << "couldn't fly" << std::endl;}
};


class duck
{
DuckData data;

FlyBehavior * bhv;
void performFly(){ bhv->fly(data); }
}
</code>


Other things to note:
- as Noah Roberts already pointed out, this example is a rather poor use of
a strategy pattern. A much better example would be a class that implements
some sort of file output where the intended file format is set through a
strategy pattern.
- try to avoid printf() and the like in C++. It may not look like it, but
iostream is your friend.


Hope this helps,
Rui Maciel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top