Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

jmerkow

macrumors newbie
Original poster
Jan 20, 2011
17
0
I am working on making something that uses multiple inheritance similar to java's implements with interfaces.

The best I can figure it the only way to do this in C++ is to make a class and make all the functions virtual and use multiple inheritance. Is there a better way to do this?

Code:
class Interface
{
    public:
        virtual void InterfaceFunction() = 0;
};

class Base
{
    public:
        virtual int BaseFunction(){\\Does something}
};

class Derived : public Base, public Interface
{
    public: 
        void InterfaceFunction(){}
        int BaseFunction(){ return Base::BaseFunction(); } // Is this needed?
};
 
Last edited:
I think a Java interface is just a class of all pure virtual member functions.

To answer the question in the comment in your code; a class inherits all the protected and public functions from its bases classes. You don't need to re-define a function in a derived class unless you want to change it.

Oh, and every class with virtual member functions should have a virtual destructor.
 
Last edited:
I think a Java interface is just a class of all pure virtual member functions.

Well, it is not. It is a list of requirements that a class needs to fulfil to be able to claim that it implements the interface. It is the same as an Objective-C protocol. There is just no such thing as an "interface" in C++; C++ doesn't have the runtime support to implement it properly.

Consider an interface A requiring two methods X and Y, and an interface B requiring two methods X and Z. And you want a class implementing both interfaces. No problem in Java or Objective-C. In C++, the "interface = abstract class" approach just doesn't work.
 
Consider an interface A requiring two methods X and Y, and an interface B requiring two methods X and Z. And you want a class implementing both interfaces. No problem in Java or Objective-C. In C++, the "interface = abstract class" approach just doesn't work.

I have asked people who claim to be fluent in C++ what happens if class C in inherits from classes A and B which both have implementations for method Y (with identical parameters and return types) and C does not override this. No one has been able to give me an answer beyond, one will beyond one of the two methods will be called and we don't know which one. I even asked this on a C++ training course and the instructor could not give a reasonable answer. This is one of the reasons I dislike C++ greatly.
 
Consider an interface A requiring two methods X and Y, and an interface B requiring two methods X and Z. And you want a class implementing both interfaces. No problem in Java or Objective-C. In C++, the "interface = abstract class" approach just doesn't work.

I know this an old thread, and I don't know if the OP is interested, but I am because I've just had to turn my mind back to C++.

As an refresher exercise, I attempt to find a solution to this requirement. Here's what I came up with. I'm rust in C++. This works, but is it good? I'd appreciate a critique.

One thing that's immediately obvious is the amount of code is going to grow exponentially with the number of interfaces and the number of member functions per interface.

InterfaceA.h
Code:
#ifndef INTERFACEA_H_INCLUDED
#define INTERFACEA_H_INCLUDED

class InterfaceA
{
public:
    virtual void x() = 0;
    virtual void y() = 0;
};

#endif

InterfaceB.h
Code:
#ifndef INTERFACEB_H_INCLUDED
#define INTERFACEB_H_INCLUDED

class InterfaceB
{
public:
    virtual void x() = 0;
    virtual void z() = 0;
};

#endif

Class.h
Code:
#ifndef CLASS_H_INCLUDED
#define CLASS_H_INCLUDED

#include "InterfaceA.h"
#include "InterfaceB.h"

class Class
{

public:
    
    Class();
    
    operator InterfaceA&() { return mInterfaceAProxy; }
    operator InterfaceA*() { return &mInterfaceAProxy; }
    operator InterfaceB&() { return mInterfaceBProxy; }
    operator InterfaceB*() { return &mInterfaceBProxy; }
    
    virtual void x();
    virtual void y();
    virtual void z();
    
    virtual ~Class() = default;

private:
    
    class InterfaceAProxy : public InterfaceA
    {
    public:
        InterfaceAProxy(Class& outer) : mOuter(outer) { }
        void x() override { mOuter.x(); }
        void y() override { mOuter.y(); }
    private:
        Class& mOuter;        
    } mInterfaceAProxy;
    
    class InterfaceBProxy : public InterfaceB
    {
    public:
        InterfaceBProxy(Class& outer) : mOuter(outer) { }
        void x() override { mOuter.x(); }
        void z() override { mOuter.z(); }
    private:
        Class& mOuter;
    } mInterfaceBProxy;
    
};

#endif

Class.cc
Code:
#include "Class.h"
#include <iostream>

using namespace std;

Class::Class()
:  mInterfaceAProxy(*this),
   mInterfaceBProxy(*this)
{
}

void Class::x() { cout << __PRETTY_FUNCTION__ << endl; }
void Class::y() { cout << __PRETTY_FUNCTION__ << endl; }
void Class::z() { cout << __PRETTY_FUNCTION__ << endl; }

Derived.h
Code:
#ifndef DERIVED_H_INCLUDED
#define DERIVED_H_INCLUDED

#include "Class.h"

class Derived : public Class
{
public:
    void x() override;
};

#endif

Derived.cc
Code:
#include "Derived.h"
#include <iostream>

using namespace std;

void Derived::x() { cout << __PRETTY_FUNCTION__ << endl; }

main.cc
Code:
#include "Class.h"
#include "Derived.h"
#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

void funcTakingA(InterfaceA&);
void funcTakingB(InterfaceB&);

void
funcTakingA(InterfaceA& a)
{
    a.x();
    a.y();
}

void
funcTakingB(InterfaceB& b)
{
    b.x();
    b.z();
}

int
main()
{    
    Class c;
    c.x(); c.y(); c.z();
    cout << "------------------" << endl;
    
    funcTakingA(c);
    funcTakingB(c);
    cout << "------------------" << endl;
    
    Derived d;
    d.x(); d.y(); d.z();
    cout << "------------------" << endl;
    
    funcTakingA(d);
    funcTakingB(d);
    cout << "------------------" << endl;
    
    vector<InterfaceA*> aVec;
    aVec.push_back(c);
    aVec.push_back(d);
    for (InterfaceA* a : aVec)
    {
        funcTakingA(*a);
    }
    cout << "------------------" << endl;
    
    vector<InterfaceB*> bVec;
    bVec.push_back(c);
    bVec.push_back(d);
    for (InterfaceB* b : bVec)
    {
        funcTakingB(*b);
    }
    cout << "------------------" << endl;
    
    return EXIT_SUCCESS;
}
 
Last edited:
I know this an old thread, and I don't know if the OP is interested, but I am because I've just had to turn my mind back to C++.

Since you dug out this old thread anyway: In Objective-C, formal protocols are about the same as Java interfaces. They are most often used for delegate objects. In my own code, I tend not to use formal protocols and delegate objects anymore, but use blocks instead. Much more flexible, much more readable code. And obviously they will work in C++ just as well.
 
In my own code, I tend not to use formal protocols and delegate objects anymore, but use blocks instead.

Alas, Apple's blocks are not yet standard C++. The code I'm writing needs to compile under VS2010 as well.

I'm sure I've forgotten the pitfalls of C++. I'm currently revising Effective C++ (3e) to try to remember.

Is there a flaw in this technique I posted? Is there some gotcha that people fresher in C++ can see?
 
I have asked people who claim to be fluent in C++ what happens if class C in inherits from classes A and B which both have implementations for method Y (with identical parameters and return types) and C does not override this. No one has been able to give me an answer beyond, one will beyond one of the two methods will be called and we don't know which one. I even asked this on a C++ training course and the instructor could not give a reasonable answer. This is one of the reasons I dislike C++ greatly.


I think more than anything, the people you were asking just aren't particularly well read. From Thinking in C++ (Eckel, Bruce) it mentions that in cases like this and in cases with the "Diamond of Death" the first inheritance path will win out (depending on how the vtable is designed on that implementation) in many implementations but that the compiler *should* jump up and down and scream at you for doing it. The proper way to call each version of the class is to cast your derived type pointer to the base class you'd like to call and invoke the function. One way to avoid this problem in the diamond of death is by using virtual inheritance.

http://progtutorials.tripod.com/cpp2.htm#_Toc50821299

One example.

The top answer here shows a way to avoid this in the first place by using an extra inheritance step to name mangle one or both of the conflicting names:

http://stackoverflow.com/questions/2004820/inherit-interfaces-which-share-a-method-name

---

In terms of pretending to make an interface for C++, I've done it before but have found that the old adage of "composition over inheritance" is often preferable (even in projects in languages that support proper interfaces). When an "interface" is the better way to do it, I follow the guidance demonstrated here:

http://stackoverflow.com/questions/318064/how-do-you-declare-an-interface-in-c
 
Thanks for stackoverflow pointers.

The proper way to call each version of the class is to cast your derived type pointer to the base class you'd like to call and invoke the function.

Interesting Item #27 ("Minimize casting") of Effective C++ (3e) explicitly advises against this.

Say you're override an inherited virtual member function virtFunc() and you want to call the inherited code first.

The item indicates this is wrong.
Code:
void Derived::virtFunc()
{
  static_cast<Base>(*this).virtFunc();
  // ...
}

It advises this instead.
Code:
void Derived::virtFunc()
{
  Base::virtFunc();
  // ...
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.