2

编写测试后,我确定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更糟

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

4

3 回答 3

2

IMO 如果确实需要基类和接口之间的解耦,则解决方案 1 和 2 都具有可容忍的开销,在当代硬件上肯定不会有任何问题。

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

我的意思是如果问题是继承了多个接口,这些接口都继承了基类,或者继承的“可怕的菱形”问题,你可以简单地使用虚拟继承

于 2015-03-16T20:25:12.610 回答
1

你的设计有一些缺陷。

您应该考虑从 Mixin 方面使用 CRTP,这样可以避免保留派生的具体指针的额外指针。

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; }
};
于 2015-03-16T20:38:21.100 回答
1

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

于 2015-03-16T20:30:58.433 回答