从接口访问具体 class 的 "this" 指针

Access "this" pointer of concrete class from interface

写测试后,我确定接口中的this指针不等于具体class的this指针,意味着我不能直接使用对其进行 C 风格转换。

class AbstractBase {...};

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

class Concrete : public AbstractBase, public AnInterface {};

我的接口需要一个基 class 指向具体 class 的指针,在构造函数和析构函数中继承它,以便处理与接口相关的注册和注销。

每个继承接口的具体对象都需要先继承抽象基础class,它总是在布局中排在第一位。

对于构造函数来说并不是那么难,我可以在接口构造函数中添加一个指针并从具体的 class 传递 this。但是析构函数没有任何参数,所以我在黑暗中。

到目前为止我想出的解决方案是有开销的:

1 - 将指针存储在析构函数中使用的接口中 - 添加一个指针的内存开销

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

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

2 - 在接口中创建一个抽象方法并将其实现到 return this 具体 class - 增加虚拟调用的间接开销

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

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

3 - dynamic_cast 更糟

有没有更有效的方法来实现这个?

IMO 如果确实需要基础 class 和接口之间的解耦,解决方案 1 和 2 的开销都可以容忍,当然在现代硬件上不会有问题。

但是既然你说接口是为了与基础中提供的功能一起工作而设计的class,那么解耦可能不是一件好事。

我的意思是,如果问题是继承多个接口,这些接口都继承了基 class、or the "dreaded diamond" problem with inheritance, you can simply use virtual inheritance

你所有的顾虑似乎都是微优化。假设您确实无法将接口与实现分开(在这种情况下,为什么首先要使用接口?)我只会使用 dynamic_cast 并完成它,即使它非常重量级。如果我被困在无法选择 RTTI 的平台上,那么我会使用选项 2。

您的设计有一些缺陷。

你应该考虑使用CRTP as from the Mixin aspect,这样你就不用再保留一个额外的具体派生指针了。

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; }
};