Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving ambiguous this pointer in C++

I'm trying to derive a new class from an old one. The base class declaration looks like this:

class Driver : public Plugin, public CmdObject
{
protected:
    Driver();

public:
    static Driver* GetInstance();
    virtual Engine& GetEngine();
public:
    // Plugin methods...
    virtual bool InitPlugin (Mgr* pMgr);
    virtual bool Open();
    virtual bool Close();

    // CmdObject
    virtual bool ExecObjCmd(uint16 cmdID, uint16 nbParams, CommandParam *pParams, CmdChannelError& error);

    Mgr *m_pMgr;

protected:
    Services *m_pServices;
    Engine m_Engine;
};

Its constructor looks like this:

Driver::Driver() : 
    YCmdObject("Driver", (CmdObjectType)100, true),
    m_Engine("MyEngine")
{
    Services *m_pServices = NULL;
    Mgr *m_pMgr = NULL;
}

So when I created my derived class, I first tried to simply inherit from the base class:

class NewDriver : public Driver

and copy the constructor:

NewDriver::NewDriver() : 
    CmdObject("NewDriver", (EYCmdObjectType)100, true),
    m_Engine("MyNewEngine")
{
    Services *m_pServices = NULL;
    Mgr *m_pMgr = NULL;
}

The compiler (VisualDSP++ 5.0 from Analog Devices) didn't like this:

".\NewDriver.cpp", line 10: cc0293:  error: indirect nonvirtual base
      class is not allowed
 CmdObject("NewDriver", (EYCmdObjectType)100, true),

That made sense, so I decided to directly inherit from Plugin and CmdObject. To avoid multiple inheritance ambiguity problems (so I thought), I used virtual inheritance:

class NewDriver : public Driver, public virtual Plugin, public virtual CmdObject

But then, in the implementation of a virtual method in NewDriver, I tried to call the Mgr::RegisterPlugin method that takes a Plugin*, and I got this:

".\NewDriver.cpp", line 89: cc0286:  error: base class "Plugin" is
      ambiguous
 if (!m_pMgr->RegisterPlugin(this))

How is the this pointer ambiguous, and how do I resolve it?

Thanks,

--Paul

like image 916
Paul Tevis Avatar asked Feb 27 '23 01:02

Paul Tevis


1 Answers

If you derive from Driver, you don't have to call the constructors of Drivers bases explicitly:

class NewDriver : public Driver { /* ... */ };
NewDriver::NewDriver() : Driver() {}

The constructor of Driver then initializes its own bases, you don't have to and shouldn't do that directly.
If it should behave differently, let it take parameters:

class Driver : /* ... */ {
public:
    Driver(const std::string& name /* , ... */)
      : CmdObject(name /* , ... */)
    {}
    // ...
};

NewDriver::NewDriver() : Driver("NewDriver" /* , ... */) {}
like image 176
Georg Fritzsche Avatar answered Mar 07 '23 16:03

Georg Fritzsche