从接口层次结构中获取接口

Posted

技术标签:

【中文标题】从接口层次结构中获取接口【英文标题】:Getting interface from Hierarchy of interfaces 【发布时间】:2014-03-04 15:10:57 【问题描述】:

我的接口层次结构如下:

class interface1

public:
    virtual ~interface1() = 0;


class interface2 : public interface1

public:
    virtual ~interface2() = 0;

我的数据模型具有可以从 Interface1 或 interface2 派生的类:

class cls1 : public interface1


class cls2 : public interface2


我想写一个在 interface1 或 interface2 上工作的重载函数

void function1(interface1 * obj)

    // do something here

void function1(interface2 * obj)

    // do something here

现在我想创建 cls1 和 cls2 的对象,并调用 function1:


    .........
    cls1 *p1 = new cls1;
    cls2 *p2 = new cls2;

    function1(p1);
    function1(p2);        
    .........

我的问题是 - 在这两种情况下,总是调用 function1(interface1 * obj)。我不想将 if-else 与 dynamic_cast 结合使用(这是创建接口层次结构的重点)。 谁能建议我用 cls2 的对象调用 function1(interface2* obj) 的方法?

【问题讨论】:

在不相关的注释中,您的析构函数似乎缺少 virtual 关键字。 我无法重现您的问题。应用了明显的修复但其他代码完全相同,gcc 使用适当的函数as expected(ideone.com) @PaF:是的,谢谢!已更正! 【参考方案1】:

您尝试执行的操作听起来与虚函数非常相似。为什么不将function1 定义为类的成员函数:

class interface1

public:
    virtual void function1()
    
        // Do what you want to do when deriving from interface1
    


class interface2 : public interface1

public:
    virtual void function1()
    
        // Do what you want to do when deriving from interface2
    

【讨论】:

这对我来说是显而易见的解决方案,但并不是那么简单。如果 function1() 和 funtion2() 是不同类的一部分,并且对 cls1 和 cls2 有不同的实现怎么办?很好的例子是访问者模式。【参考方案2】:

比我知识渊博的人告诉我,依靠编译器隐式检测你想要的类的返回值是个坏主意。这可能会导致无穷无尽的问题,因为有时它们的选择与您的预期不同。

因此,在这种情况下,我会使用显式强制转换,例如

function1( static_cast<interface1*>( p1 ));
function1( static_cast<interface2*>( p2 ));

我知道它没有那么紧凑,但如果你在一年后查看你的代码,它会更有意义。

【讨论】:

【参考方案3】:

从比其他答案更高级的角度来看:您要完成的是根据参数的类型调度函数调用。 C++ 一般不支持这个。

有两种选择:

    正如@PaF 所写,您可以将函数设为虚拟。 如果你真的不想让函数作为类成员,你可以模拟所谓的双重调度(根据调用它的对象来确定要调用的函数)作为参数的类型)通过应用访问者模式。这样,您可以根据参数的类型调用函数,同时避免 dynamic_cast。

【讨论】:

以上是关于从接口层次结构中获取接口的主要内容,如果未能解决你的问题,请参考以下文章

IOC类图

使用 MDX 从层次结构中获取当前会计年度

从 Angular 6 材质树中的子节点获取父层次结构

实体框架中的类和接口层次结构?

怎么从接口里获取数据、、

如何在雪花中获取用户角色层次结构?