Access “this” pointer of concrete class from interface

不羁岁月 提交于 2019-12-22 19:13:08

问题


After writing a test, I determined that the this pointer in an interface is not equal to the this pointer of the concrete class, meaning I can't just use a C-style cast on it.

class AbstractBase {...};

class AnInterface {
public:
    AnInterface() {...} // need AbstractBase * here 
    ~virtual AnInterface() {...} // and here
};

class Concrete : public AbstractBase, public AnInterface {};

My interface needs a base class pointer to the concrete class inheriting it in the constructor and destructor in order to handle interface related registration and deregistration.

Every concrete object that inherits the interface needs to inherit the abstract base class first, it is always first in the layout.

For the constructor it is not all that hard, I can add a pointer in the interface constructor and pass this from the concrete class. But the destructor doesn't have any parameters, so I am in the dark there.

The solutions I came up with so far come with overhead:

1 - store the pointer in the interface to be used in the destructor - adds in one pointer worth of memory overhead

class AnInterface {
public:
    AnInterface(AbstractBase * ap) {...}
    ~virtual AnInterface() {...} // and here
private:
    AbstractBase * aPtr;
};

...
Concrete() : AnInterface(this) {}

2 - create an abstract method in the interface and implement it to return this in the concrete class - adds in the overhead of indirection for the virtual call

class AnInterface {
    virtual AbstractBase * getPtr() = 0;
};

class Concrete : public AbstractBase, public AnInterface {
    AbstractBase * getPtr() { return this; }
};

3 - dynamic_cast is even worse

Is there a more efficient way to achieve this?


回答1:


IMO if decoupling between the base class and the interface is really needed, both solution 1 and 2 have tolerable overheads, certainly nothing that will be a problem on contemporary hardware.

But since you say that the interface is designed to work with the functionality, provided in the base class, then maybe the decoupling is not a good thing.

I mean if the problem is with inheriting multiple interfaces which all inherit the base class, or the "dreaded diamond" problem with inheritance, you can simply use virtual inheritance.




回答2:


All of your concerns seem like micro-optimizations. Assuming you truly can't separate out your interface from your implementation (in which case, why are you using interfaces in the first place?) I would just use dynamic_cast and be done with it, even though it's pretty heavyweight. If I were stuck on a platform where RTTI isn't an option then I'd use option 2.




回答3:


Your design has some flaws.

You should consider using CRTP as from the Mixin aspect, which saves you from keeping an extra pointer of the concrete derived.

template<typename Derived>
class AnInterface {
public:
    AnInterface() {
       Derived* derived = static_cast<Derived*>(this);
       AbstractBase* abstractBase = static_cast<AbstractBase*>(derived);
    } // have AbstractBase * here 
    ~virtual AnInterface() {...} // and here
};

class Concrete 
: public virtual AbstractBase
, public AnInterface<Concrete> {
    AbstractBase * getPtr() { return this; }
};


来源:https://stackoverflow.com/questions/29085834/access-this-pointer-of-concrete-class-from-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!