Connecting Tech Pros Worldwide Forums | Help | Site Map

Multiple Inheritance

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#1: Dec 3 '05
Hi all,

I have somes classes that have the same concept.
I would like to instance one of them depending on a condition

Something like this

MyObj myObj;

if (i==0)
myObj = new classA();
else if (i==1)
myObj = new classB();
else
myObj = new classC();
myObj ->DoSomething();

How to do this ?

thanks in advance

Nicolas H.


Jonathan Mcdougall
Guest
 
Posts: n/a
#2: Dec 3 '05

re: Multiple Inheritance


nicolas.hilaire@motorola.com wrote:[color=blue]
> Hi all,
>
> I have somes classes that have the same concept.
> I would like to instance one of them depending on a condition
>
> Something like this
>
> MyObj myObj;[/color]

MyObj *myObj;
[color=blue]
> if (i==0)
> myObj = new classA();
> else if (i==1)
> myObj = new classB();
> else
> myObj = new classC();
> myObj ->DoSomething();
>
> How to do this ?[/color]

Well this works.

If you are looking for something more generic, google for "object
factory c++". I also suggest reading Modern C++ Design by Alexandrescu
(http://erdani.org/).


Jonathan

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#3: Dec 3 '05

re: Multiple Inheritance


this doesn't work, what is the class of myObj ?

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#4: Dec 3 '05

re: Multiple Inheritance


trying to implement a factory, i try :

class A
{
public:
virtual void DoSomething();
};

class B : public A
{
public:
B() { cout << "Constructor of B" << endl; }
void DoSomething() { cout << "Do something from B" << endl; }
};

class C : public A
{
public:
C() { cout << "Constructor of C" << endl; }
void DoSomething() { cout << "Do something from C" << endl; }
};

class Factory
{
public:
A* Create(int i)
{
if (i)
return new B();
else
return new C();
}
};

int main(int argc, char* argv[])
{
Factory myFactory;
A * a = myFactory.Create(0);
a->DoSomething();
return 0;
}


but this gives me an error : error LNK2001: unresolved external symbol
"public: virtual void __thiscall A::DoSomething(void)"
(?DoSomething@A@@UAEXXZ)

How should i do ??

thanks for your help

Jonathan Mcdougall
Guest
 
Posts: n/a
#5: Dec 3 '05

re: Multiple Inheritance


nicolas.hilaire@motorola.com wrote:[color=blue]
> trying to implement a factory, i try :[/color]

Next time, quote the message you are answering to, like I do in this
post.
[color=blue]
> class A
> {
> public:
> virtual void DoSomething();[/color]

A virtual function *must* be implemented. That's why you are receiving
a linker error.

virtual void DoSomething()
{
}

"But this DoSomething() has nothing to do!" That's right, so make it
*pure* virtual.

virtual void DoSomething() = 0;

That way

1) the function is virtual (may be overrided by derived classes and
correctly called using a pointer to base class)
2) the function has no implementation
a) making the class "abstract" (may not be instantiated)
b) forcing the derived classes to implement the function

Also, if you intend to delete derived objects from a base pointer:

void f(Base *b)
{
delete b;
}

int main()
{
Derived *d = new Derived;
f(d);
}

you *must* make the destructor virtual or you'll get undefined behavior
(very probably, the wrong destructor will be called and memory may be
leaked).

class Base
{
public:
virtual ~Base() {}
};
[color=blue]
> };
>
> class B : public A
> {
> public:
> B() { cout << "Constructor of B" << endl; }
> void DoSomething() { cout << "Do something from B" << endl; }
> };
>
> class C : public A
> {
> public:
> C() { cout << "Constructor of C" << endl; }
> void DoSomething() { cout << "Do something from C" << endl; }
> };
>
> class Factory
> {
> public:
> A* Create(int i)
> {
> if (i)
> return new B();
> else
> return new C();
> }[/color]

Well, that's a very good starting point.

The problem here is that Factory is a "dependency bottleneck". That
means Factory needs to know about all the possible classes it can
create. It would be better better if the classes themselves could
register to the factory. But that's an "advanced" subject so I suggest
you begin with your Factory class. Someday, you'll realize that not
only is it complicated to add new classes to your hierarchy, but it
takes a while to recompile your program everytime you make a single
change to one header. When that time arrives, look for the references I
gave you.
[color=blue]
> };
>
> int main(int argc, char* argv[])
> {
> Factory myFactory;
> A * a = myFactory.Create(0);
> a->DoSomething();
> return 0;
> }
>
>
> but this gives me an error : error LNK2001: unresolved external symbol
> "public: virtual void __thiscall A::DoSomething(void)"
> (?DoSomething@A@@UAEXXZ)
>
> How should i do ??[/color]

This should be solved by either implementing the virtual function or
(more probably) by making it pure virtual (with the =0 thing at the
end).


Jonathan

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#6: Dec 3 '05

re: Multiple Inheritance


[color=blue]
> This should be solved by either implementing the virtual function or
> (more probably) by making it pure virtual (with the =0 thing at the
> end).
>
>
> Jonathan[/color]


Thanks for your answer Jonathan, making the method virtual pure solved
my problem.

I know that it would be more efficient with using a "template" factory,
but for now, i'm only abble to do something simple :)

I thought first that multiple inheritance would solve my problem, but
with a factory it should be better.

Thanks again

Nicolas H.

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#7: Dec 3 '05

re: Multiple Inheritance


>you *must* make the destructor virtual or you'll get undefined behavior[color=blue]
>(very probably, the wrong destructor will be called and memory may be
>leaked).[/color]

This helped me too :))

I've modified my Factory class
class Factory
{
A * object;
public:
A* Create(int i)
{
if (i)
object = new B();
else
object = new C();
return object;
}
~Factory()
{
cout << "Destructor of Factory" << endl;
delete object;
}
};

and made the base destructor as virtual


Thanx again

Viktor Prehnal
Guest
 
Posts: n/a
#8: Dec 3 '05

re: Multiple Inheritance


Hi,
something on static polymorfism might help

http://osl.iu.edu/~tveldhui/papers/techniques/

item 1.3

Regards, Viktor

Jonathan Mcdougall
Guest
 
Posts: n/a
#9: Dec 3 '05

re: Multiple Inheritance



nicolas.hilaire@motorola.com wrote:[color=blue][color=green]
> >you *must* make the destructor virtual or you'll get undefined behavior
> >(very probably, the wrong destructor will be called and memory may be
> >leaked).[/color]
>
> This helped me too :))
>
> I've modified my Factory class
> class Factory
> {
> A * object;
> public:
> A* Create(int i)
> {
> if (i)
> object = new B();
> else
> object = new C();
> return object;
> }
> ~Factory()
> {
> cout << "Destructor of Factory" << endl;
> delete object;
> }
> };[/color]

That may work, but the whole point of a factory is to have a separate,
"clean" way to create objects, like your first attempt. A factory
usually has only static members, it is not meant to be instantiated.

class Factory
{
public:
static Base *create(int id)
{
// switch on id and returns a new object
}
};

int main()
{
Base *b = Factory::create(my_id);
}

Another way would be to make Factory a singleton (google on that). But
again, you may not need a full-fledged factory.
[color=blue]
> and made the base destructor as virtual[/color]

Good.


Jonathan

nicolas.hilaire@motorola.com
Guest
 
Posts: n/a
#10: Dec 5 '05

re: Multiple Inheritance


> That may work, but the whole point of a factory is to have a separate,[color=blue]
> "clean" way to create objects, like your first attempt. A factory
> usually has only static members, it is not meant to be instantiated.
>
> class Factory
> {
> public:
> static Base *create(int id)
> {
> // switch on id and returns a new object
> }
> };
>
> int main()
> {
> Base *b = Factory::create(my_id);
> }
>
> Another way would be to make Factory a singleton (google on that). But
> again, you may not need a full-fledged factory.
>[/color]


Ok, thanks Jonathan, i will look forward to make the Factory as static
and maybe why not a singleton.

In this way, maybe look to a function that will safely delete the
object (like you mentionned before)



[color=blue][color=green]
>>Viktor Prehnal
>>Hi, something on static polymorfism might help
>> http://osl.iu.edu/~tveldhui/papers/techniques/item 1.3
>> Regards, Viktor[/color][/color]

Thanks Viktor, i will have a look on this :))


Nicolas H.

Closed Thread