Mixing interface and functional inheritance

K

Kevin L

Below is a code snippet that fails to compile under vc.net

class BaseInterface
{
public:
virtual void f() = 0;
};

class BaseImplementation : public BaseInterface
{
public:
void f(){}
};

class ExtraInterface : public BaseInterface
{
virtual void g() = 0;
};

class ExtraImplementation: public BaseImplementation, public
ExtraInterface
{
void g(){}
};

void func()
{
ExtraImplementation d;
}

The compiler complains that ExtraImplementation is an abstract class
and therefore cannot be initialized. Function f, despite being
defined in BaseImplementation, is undefined in ExtraImplementation.

I hope it's clear what I'm trying to do, i.e., maintaining two
inheritance lines that parallel each other. One line consists of
interfaces and the other implementation. Am I misguided in my
efforts?

Kevin
 
A

Alf P. Steinbach

Below is a code snippet that fails to compile under vc.net

class BaseInterface
{
public:
virtual void f() = 0;
};

class BaseImplementation : public BaseInterface
{
public:
void f(){}
};

class ExtraInterface : public BaseInterface
{

-- public:

virtual void g() = 0;
};

class ExtraImplementation: public BaseImplementation, public
ExtraInterface
{

-- public:

void g(){}
};

void func()
{
ExtraImplementation d;
}

The compiler complains that ExtraImplementation is an abstract class
and therefore cannot be initialized. Function f, despite being
defined in BaseImplementation, is undefined in ExtraImplementation.

The compiler is correct.

In Java you can inherit a function spec from an interface, and an
implementation of that function from a concrete class. In C++ the
two inheritance chains are distinct, functions in one don't map
onto functions in the other, unless you use virtual inheritance,
which is both messy and a tad inefficient.

Instead of using virtual inheritance (the tech level solution) I
recommend _factoring out_ the ExtraInterface, like this:


class ExtraInterface
{
public:
virtual void g() = 0;
};


Now isn't that nice?

I hope it's clear what I'm trying to do, i.e., maintaining two
inheritance lines that parallel each other. One line consists of
interfaces and the other implementation.

You can do that as shown above.

I do not recommend the virtual inheritance alternative.


Am I misguided in my efforts?

Not enough information to say, but probably not; however, it seems
you come from a Java or perhaps C# background, and need to ditch
much of the low-level details from the previous language, while
holding on the high-level concepts (which you'll have to _implement_,
some times by adhering strictly to some convention, in C++).
 
G

Gianni Mariani

Kevin said:
Below is a code snippet that fails to compile under vc.net

class BaseInterface
{
public:
virtual void f() = 0;
};

class BaseImplementation : public BaseInterface
{
public:
void f(){}
};

class ExtraInterface : public BaseInterface
{
virtual void g() = 0;
};

class ExtraImplementation: public BaseImplementation, public
ExtraInterface
{
void g(){}
};

void func()
{
ExtraImplementation d;
}

The compiler complains that ExtraImplementation is an abstract class
and therefore cannot be initialized. Function f, despite being
defined in BaseImplementation, is undefined in ExtraImplementation.

I hope it's clear what I'm trying to do, i.e., maintaining two
inheritance lines that parallel each other. One line consists of
interfaces and the other implementation. Am I misguided in my
efforts?

The virtual inheritance mechanism is what is intended to solve the problem.

class BaseInterface
{
public:
virtual void f() = 0;
};

class BaseImplementation : public *virtual* BaseInterface
{
public:
void f(){}
};

class ExtraInterface : public *virtual* BaseInterface
{
virtual void g() = 0;
};

class ExtraImplementation: public BaseImplementation, public
ExtraInterface
{
void g(){}
};

void func()
{
ExtraImplementation d;
}
 
K

Kevin L

-- public:



-- public:

....

Instead of using virtual inheritance (the tech level solution) I
recommend _factoring out_ the ExtraInterface, like this:


class ExtraInterface
{
public:
virtual void g() = 0;
};
....
Ah, but now I can't pass an object of ExtraImplementation as
ExtraInterface and have the BaseInterface functions available without
casting.

Now if I stick to strict abstract classes for the interfaces (no data
members), I can sidestep much of the messiness involved in virtual
inheritance, correct? The inheritance tree I am building is meant for
exception classes. I expect them to be constructed and used quite
infrequently. Right now I'm leaning toward the virtual inheritance
solution. Any reason not to?

Thanks for the reply.

Kevin
 
A

Alf P. Steinbach

...
Ah, but now I can't pass an object of ExtraImplementation as
ExtraInterface and have the BaseInterface functions available without
casting.

First, you _can_ hardwire the relationship, via an accessor method
in ExtraInterface.

But, second, why would you want to do that?


Now if I stick to strict abstract classes for the interfaces (no data
members), I can sidestep much of the messiness involved in virtual
inheritance, correct? The inheritance tree I am building is meant for
exception classes. I expect them to be constructed and used quite
infrequently. Right now I'm leaning toward the virtual inheritance
solution. Any reason not to?

1 In the most derived class you may have to call the constructor of
the root class.

2 Virtual inheritance mixed with non-virtual inheritance is very
messy. You're in for a maintainance nightmare.

3 It's a tad inefficient, also.
 

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

Members online

No members online now.

Forum statistics

Threads
474,142
Messages
2,570,819
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top