extending an interface

C

Christof Warlich

Hi,

I'm looking for a more concise way than below to extend an existing
interface.
Just imagine that class Interface would have 1000 other members and class
DerivedInterface only needs to add / modify _one_ member. The implementation
shall remain invisible to the application (i.e. main()).

Thanks for any suggestions,

Christof

#include <stdio.h>

class Interface {
public:
static Interface *create(void);
virtual void a(void) = 0;
virtual void b(void) = 0;
// and 1000 other pure virtual functions
};

class DerivedInterface: public Interface {
public:
DerivedInterface(void):
_base(Interface::create()) {
}
void a(void) {
printf("A\n");
}
void b(void) {
_base->b();
}
// and the 1000 other, unmodified functions
private:
Interface *_base;
};

int main(void) {
Interface *base = Interface::create();
base->a();
base->b();
Interface *derivedInterface = new DerivedInterface();
derivedInterface->a();
derivedInterface->b();
}

// everything below shall be kept invisible to the compilation unit

class Implementation: public Interface {
public:
void a(void) {
printf("a\n");
}
void b(void) {
printf("b\n");
}
};

Interface *Interface::create(void) {
return new Implementation;
}
 
J

Jonathan Mcdougall

Christof said:
Hi,

I'm looking for a more concise way than below to extend an existing
interface.
Just imagine that class Interface would have 1000 other members and class
DerivedInterface only needs to add / modify _one_ member. The implementation
shall remain invisible to the application (i.e. main()).

Thanks for any suggestions,

If you only want to override certain member functions, you'll have to
use inheritance. The base will have to implement its virtual (non pure)
member functions to provide a "default" behavior. Derived classes will
be free to either 1) change the behavior by overriding the virtual
functions or 2) let the base class do the job.

Now if you don't inherit from a base class which provide an
implementation (as you do), it's impossible.
Christof

#include <stdio.h>

class Interface {
public:
static Interface *create(void);
virtual void a(void) = 0;
virtual void b(void) = 0;
// and 1000 other pure virtual functions
};

class DerivedInterface: public Interface {
public:
DerivedInterface(void):
_base(Interface::create()) {
}
void a(void) {
printf("A\n");
}
void b(void) {
_base->b();
}
// and the 1000 other, unmodified functions
private:
Interface *_base;
};

I don't know about your design much, but you could have Inteface do
DerivedInterface's job:

class Interface {
public:

Interface();

virtual void a()
{
impl_->a();
}

virtual void b()
{
impl_->b();
}

// and 1000 other pure virtual functions

private:
Interface *impl_;
};

class DerivedInterface: public Interface {
public:
DerivedInterface()
{
}

void a()
{
printf("A\n");
}
};

class Implementation: public Interface {
public:
void a()
{
printf("a\n");
}

void b()
{
printf("b\n");
}
};

Interface::Interface()
: impl_(new Implementation)
{
}

That's pretty much the Pimpl pattern. It changes the design, but I
think it's the only way to achieve your goal.


Jonathan
 
V

Victor Bazarov

Christof said:
I'm looking for a more concise way than below to extend an existing
interface.

What does it mean (in your POV) "to extend an existing interface"?
I understand it as "define another interface with more functions".
Just imagine that class Interface would have 1000 other members and class
DerivedInterface only needs to add / modify _one_ member.

So, is it "add" or "modify"?
> The
implementation
shall remain invisible to the application (i.e. main()).

What does that mean?
Thanks for any suggestions,

Christof

#include <stdio.h>

class Interface {
public:
static Interface *create(void);
virtual void a(void) = 0;
virtual void b(void) = 0;
// and 1000 other pure virtual functions
};

class DerivedInterface: public Interface {

If you derive publicly to establish conversions (the "is-a" relationship),
then you have to deal with the consequences (like the need to define all
pure functions to make this class concrete). Such are the rules.
public:
DerivedInterface(void):
_base(Interface::create()) {
}
void a(void) {
printf("A\n");
}
void b(void) {
_base->b();
}
// and the 1000 other, unmodified functions

What do you mean by "unmodified"? They are pure, aren't they? So, you
need to define them _all_ here.
private:
Interface *_base;
};

int main(void) {
Interface *base = Interface::create();
base->a();
base->b();
Interface *derivedInterface = new DerivedInterface();
derivedInterface->a();
derivedInterface->b();
}

// everything below shall be kept invisible to the compilation unit

class Implementation: public Interface {
public:
void a(void) {
printf("a\n");
}
void b(void) {
printf("b\n");
}
};

Interface *Interface::create(void) {
return new Implementation;
}

You can't expect your 'DerivedInterface' class to suddenly become concrete
(instantiable) without defining all pure virtual functions in 'Interface'.
What you should be looking at is another way to create an 'Interface*' by
some factory method without redefining the whole bag of virtual functions.
IOW, you need to create a 'DerivedImplementation' as well as the
'DerivedInterface':

class ABC {
public:
static ABC* create();
static void destroy(ABC*);

virtual ~ABC() {}
virtual void a() = 0;
virtual void b() = 0;
};

class ABC2 : public virtual ABC {
public:
static ABC2* create();
static void destroy(ABC2*);

virtual void c() = 0;
};

int main() {
ABC* abc = ABC::create();
abc->a();
abc->b();
ABC::destroy(abc);

ABC2* abc2 = ABC2::create();
abc2->a();
abc2->b();
abc2->c();
ABC2::destroy(abc2);
}
-------------------------------------------- elsewhere
#include <iostream>
class ABC_impl : public virtual ABC {
public:
void a() { std::cout << "ABC_impl::a\n"; }
void b() { std::cout << "ABC_impl::b\n"; }
};

#include <iostream>
class ABC2_impl : public ABC2, public ABC_impl {
public:
void c() { std::cout << "ABC2_impl::c\n"; }
};

ABC* ABC::create() {
return new ABC_impl;
}

void ABC::destroy(ABC* abc) {
delete abc;
}

ABC2* ABC2::create() {
return new ABC2_impl;
}

void ABC2::destroy(ABC2* abc2) {
delete abc2;
}


V
 
C

Christof Warlich

Hi Jonathan, Victor,

thanks a lot for the comprehensive help. My goal was to strictly
separate the interface
from the implementation, which works fine as long as inheritance in not
needed, while
it becomes somewhat ugly when implementation of a derived class just
with the knowledge
of the interface is necessary.

Cheers,

Christof
 

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
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top