我有一个类实现了2的接口和继承1类。因此,一般看起来是这样的:

class T : public A, public IB, public IC {
};

有一点在代码在哪里我有一个 IB *, 但真的可以使用一个 A *.我希望,一个动态的投会是这样的:

IB *b_ptr = new T; // it's really more complicated, but serves the example
A *a_ptr = dynamic_cast<A *>(b_ptr);

不幸的是,这不起作用。是否有一个适当的方式做到这一点?或者我应该实施工作?我已经想过既有 IBIC 继承的几乎从 A, 但请参考上一次我试过,有一些并发症,即使它不希望的。

任何想法?

编辑:哦,是啊,这是一个插件API,因此不幸的是我没有直接访问 T 类型在这里我需要的 A *.我已经那么接下来,但如前所述,这是更为复杂。基本上我有2个共用图书馆。 TT1 (在这里我有一个 IB *)是两个类实现一个插件API和内部的共享图书馆。

为了澄清:这里有一个更具体的例子,我的典型的插件(他们是在单独的图书馆):

插件:

class PluginA : public QObject, public PluginInterface, public OtherInterface {
};

插件B:

class PluginB : public QObject, public PluginInterface {
    // in here, I have a PluginInterface *, but really could use a QObject *
    // unfortunately, PluginB has absolutely no knowledge of the "PluginA" type
    // it just so happens that my PluginInterface * pointer points to an object of type
    // PluginA.
};

编辑:我有个猜测的问题是,pluginA和pluginB是在不同的公共图书馆。也许rtti不交叉的模块边界。我想这可能是这种情况,因为人民的例子似乎工作的现在我的测试。具体地说,pluginB没有"所属类别进PluginA"如果我做一个"nm"。这可能是核心的问题。如果是这种情况,我将只需要工作围绕着它无论是通过虚拟继承或一个虚拟的 cast_to_qobject() 能在我的一个接口。

有帮助吗?

解决方案 4

我终于想通了, 丹尼尔Paull 是正确的,在这一"横向 dybnamic_cast"应该允许的。我的问题是因为我的代码是涉及公共图书馆。的所属类别从PluginA是不可PluginB.我的解决方案是有效地加 RTLD_NOWRTLD_GLOBAL 我载程序

技术上这是

loader.setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);

因为我使用夸脱的插件系统,但同样的差别。这些标志的力量所有的符号从图书馆加载到可以立即解决,可以看到其他图书馆。因此使得所属类别提供给大家,需要它。的 dynamic_cast 工作预计一旦这些标志。

其他提示

每一类至少有一个虚拟的方法?如果不是,那是你的问题。增加一个虚拟析构到每一类应该克服的问题。

以下愉快地作为我说:

class IC
{
public:
    virtual ~IC() {}
};

class IB
{
public:
    virtual ~IB() {}
};

class A
{
public:
    virtual ~A() {}
    void foo() { /* stick a breakpoint here to confirm that this is called */ }
};

class T : public A, public IB, public IC 
{
public:
    virtual ~T() {}
};


int main(void)
{
    IB *b_ptr = new T;
    A *a_ptr = dynamic_cast<A *>(b_ptr);
    a_ptr->foo();
    return 0;
}

编辑:

之后所有新的信息,以及不寻常的行为(代码应该只是工作!), 不会的以下帮助吗?我已经介绍了一个接口,称为IObject和使用虚拟的继承,确保只有一个副本的这个基类。你可以现在投向IObject然后到一个?

class IObject
{
public:
    virtual ~IObject() {}
};

class IC : virtual public IObject
{
public:
    virtual ~IC() {}
};

class IB : virtual public IObject
{
public:
    virtual ~IB() {}
};

class A : virtual public IObject
{
public:
    virtual ~A() {}
    void foo() { /* stick a breakpoint here to confirm that this is called */ }
};

class T : virtual public A, virtual public IB, virtual public IC
{
public:
    virtual ~T() {}
};


int main()
{
    IB *b_ptr = new T;
    A *a_ptr = dynamic_cast<A *>( dynamic_cast<IObject *>(b_ptr) );
    a_ptr->foo();
    return 0;
}

我不认为这是正确的解决方案,但它可能会提供一些信息为什么...

是否有一个适当的方式做到这一点?或者我应该实施工作?我已经想过既具有IB和IC继承的几乎从一,但是请参考上一次我试过,有一些并发症,即使它不希望的。

我把它然后,这些定义的IB和IC是在你的控制之下。

还有的方式在其COM接口工作窗口;这些做什么,你是想要做的事,即:

  • 从一个到另一个接口
  • 执行是不透明的到来电
  • 只有实施知道其它实现接口

不这样做,你可以做这样的事情(未经测试的代码之前)...

interface IQueryInterface
{
  IQueryInterface* queryInterface(const Guid* interfaceId);
};

interface IB : public abstract IQueryInterface
{
  ...
};

interface IC : public abstract IQueryInterface
{
  ...
};

//within your implementation class
IQueryInterface* T::queryInterface(const Guid* interfaceId)
{
  if (matches(interfaceId,GUID_IB))
    return (IB*)this;
  if (matches(interfaceId,GUID_IC))
    return (IC*)this;
  if (matches(interfaceId,GUID_A))
    return (A*)this;
  return 0;
}

一个更简单、更硬编码版本,这将是:

class A; //forward reference
interface IB
{
  virtual A* castToA() { return 0; }
};
class T : public A, IB, IC
{
  virtual A* castToA() { return this; }
};

投到一个T*第一然后到:

IB *b_ptr = new T; // it's really more complicated, but serves the example
A *a_ptr = dynamic_cast<T *>(b_ptr);

如果IB一般应该料到,那么也许IB应该继承A.

编辑:我只是想这个和它的工作-注意,E是未知的时间编写的主要方法。

struct A
{
    virtual ~A() {}
};

struct C
{
    virtual ~C() {}
};

A* GetA();

int main()
{
    C *y = dynamic_cast<C *>(GetA());
    if (y == NULL)
        cout << "Fail!";
    else
        cout << "Ok!";
}

struct E : public A, public C
{
}; 

A* GetA() { return new E(); }

我最近也被打扰,同样的问题。更多信息,请参见海湾合作委员会的常见条目:

http://gcc.gnu.org/faq.html#dso

除了指示dlopen里与RTLD_*旗,一些身的这个问题可以解决的链接,以及,看看它-E-Bsymbolic的选择。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top