访问"这"来自接口的具体类的指针

时间:2015-03-16 19:57:28

标签: c++ interface base-class concreteclass

编写测试后,我确定接口中的this指针不等于具体类的this指针,这意味着我不能只使用C风格的转换它

class AbstractBase {...};

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

class Concrete : public AbstractBase, public AnInterface {};

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

继承接口的每个具体对象都需要首先继承抽象基类,它始终是布局中的第一个。

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

到目前为止,我提出的解决方案都有开销:

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

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

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

2 - 在接口中创建一个抽象方法并实现它以在具体类中返回this - 增加虚拟调用的间接开销

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

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

3 - dynamic_cast更糟糕

有没有更有效的方法来实现这一目标?

3 个答案:

答案 0 :(得分:2)

IMO如果真的需要在基类和接口之间进行解耦,解决方案1和解决方案2都有可容忍的开销,当然在现代硬件上没有任何问题。

但是既然你说接口设计用于基类中提供的功能,那么解耦可能不是一件好事。

我的意思是如果问题是继承多个继承基类or the "dreaded diamond" problem with inheritance, you can simply use virtual inheritance的接口。

答案 1 :(得分:1)

您所有的担忧似乎都是微观优化。假设你真的无法将你的界面从你的实现中分离出来(在这种情况下,为什么你首先使用接口?)我会使用dynamic_cast并完成它,即使它&# 39;相当重量级。如果我被困在一个RTTI不是一个选项的平台上,那么我就会使用选项2.

答案 2 :(得分:1)

你的设计有一些缺陷。

您应该考虑使用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; }
};