Re: OOP design problem with dynamic_cast
Leslaw Bieniasz wrote:
>
> Hello,
>
> I have the following OOP design problem. I have a base class
> designed as an element of a list, let's say:
>
> class A
> {
> public:
> // some stuff
>
> A* Next;
> A* Prev;
> }
Don't forget the semicolon.
>
> in which pointers Next and Prev serve for accessing next and
> previous elements in the list. For simplicity, I declare here all
> contents as public.
>
> Class A is abstract. In practice, real lists are constructed using
> various kinds of derived classes, for example:
Well, you didn't make A abstract, did you?
>
>
> class B : public A
> {
> public:
> // some stuff
>
> B_Data *Data;
> void foo(void);
> }
(semicolon)
>
>
> where B_Data is some data specific to class B, and method foo
> serves for operations on Data. However, I need to be able to access
> in foo not only the data in a given object, but also in other objects
> in the list. Thus, I need to do something like this:
>
> void B::foo(void)
> {
> B* bnext = dynamic_cast<B*>(Next);
> B* bprev = dynamic_cast<B*>(Prev);
>
> Data = bnext->Data + bprev->Data; // for example
>
> // etc.
> }
>
>
> My question is: Is there any neat possibility for redesigning
> the above construction, in order to avoid dynamic casting in foo?
> [snip]
I would offer two simple alternatives.
1) Use std::list from the standard library and get rid of A:
// note: code not tested
class B
{
public: void bar();
};
std::list<B> ls;
ls.push_back(B());
ls.push_back(B());
std::for_each(ls.begin(), ls.end(), std::mem_fun(B::bar));
2) Make class A a class template:
// Note: code not tested
template <typename T>
class A
{
public: // note: not encapsulating...
T* prev;
T* next;
T val;
template <typename U>
A(T* p, T* n, const U& u):val(u){}
virtual ~A(){}
};
class B
{
public:
void bar();
};
void foo(A<B>& node) // example
{
A<B>* p = &node;
while (p != 0)
{
p->val.bar();
p = p->next;
}
}
IMHO you should be more cautious when using inheritance. Generally this
kind of data structuring doesn't not fit into the domain of OOP so B
should not inherit from A, never.
>
> L. B.
Regards,
Ben