【问题标题】:Implementation of interface接口的实现
【发布时间】:2012-08-26 00:24:36
【问题描述】:

我有一个接口和一些实现。但在一种实现中,我有一个指定功能,仅在该实现中使用。

class Interface
{
    virtual void foo() = 0;
}

class D1 : public Interface
{
    void foo() {}
}

class D2 : public Interface
{
    void foo() {}
    void bar() {}
}

所以我只有在 D2 中有一个 D2::bar() 函数,并且它仅指定用于 D2 实现。 使用 OOP 编写这类东西的正确方法是什么?

在我的客户端代码中,我有一个电话: 接口* i; i->foo();

但如果是“i”中的 D2,在某些情况下我需要调用 bar() 函数。

【问题讨论】:

  • 你是从 Interface 继承 D1 和 D2 吗?
  • 是的,对不起,我忘了继承。固定。
  • 必须在Interface中定义virtual析构函数,否则有危险。

标签: c++ oop interface implementation


【解决方案1】:

如果需要调用bar函数,需要有一个知道bar的对象的引用。

所以,要么你引用一个 D2 对象,要么你的接口必须包含一个 bar 函数。在后一种情况下,您的 D1 也必须实现它,但实现可以为空或返回错误值。

【讨论】:

  • 好的,我有 1 个接口和 5 个实现。只有在一个实现中,我才有一些特定的功能。你说,我只需要在一种情况下实现它,而在其他情况下,我需要编写类似:void bar() {}。但我认为这不是解决该问题的正确方法。
  • 那么你的设计有问题。奇怪的是,您在特定点需要一个特定功能,而这对于接口的其他实现完全没有意义。当你使用接口时,它应该在一个你只需要知道你的接口的上下文中,你的接口应该能够做你需要的一切。
【解决方案2】:

如果你坚持使用接口,你应该把bar移到一个专用接口,然后让客户使用它:

class FooInterface {
public:
    virtual void foo() = 0;
};

class BarInterface {
public:
    virtual void bar() = 0;
};

class D1 : public FooInterface {
public:
    void foo() {}
};

class D2 : public FooInterface,
           public BarInterface {
public:
    void foo() {}
    void bar() {}
};

您需要bar 实现的客户端代码然后可以采用BarInterface。

【讨论】:

  • 但在客户端应用程序中,我的代码仅使用一个接口。例如一个“接口数组”和一些使用它的代码。
【解决方案3】:

假设您从接口继承 D1 和 D2。您可以使用强制转换将基指针转换为派生对象并使用它,前提是基指针指向D2

【讨论】:

  • 客户端对接口的实现一无所知。
  • @fryme:是的,客户不需要对此一无所知
【解决方案4】:

如果你准备在你的界面中有一些通用的实现,你可以在你的界面中放置一个 bar() 的空实现:

class Interface
{
    virtual void foo() = 0;
    virtual void bar() {}
}

class D1 : public Interface
{
    void foo() {}
}

class D2 : public Interface
{
    void foo() {}
    void bar() {}
}

现在当你调用接口 i* = blah;我->酒吧();如果 i 是 D1,它什么也不做,如果 i 是 D2,它会做 D2 特定的事情。

【讨论】:

    【解决方案5】:
    class _interface
    {
        virtual void foo() = 0;
    };
    
    class _abstract : public _interface
    {
    public:
        _abstract(){}
        virtual ~_abstract(){};
    
        virtual void foo() = 0;
        int get_type()
        {
            return i_type;
        }
    
    protected:
        int i_type;
    };
    
    class D1 : public _abstract
    {
    public:
        D1(){
            i_type = 1;
        }
        ~D1(){}
    
        void foo() {
            // do something
        }
    };
    
    class D2 : public _abstract
    {
    public:
        D2(){
            i_type = 2;
        }
        ~D2(){}
    
        void foo() {
            // do something
        }
    
        void bar() {
            // do something
        }
    };
    int main()
    {
        D1 d_one;
        D2 d_two;
    
        _abstract* ab = &d_one;
        cout << ab->get_type() << "D1" << endl;
    
        ab = &d_two;
        cout << ab->get_type() << "D2" << endl;
    
        return 0;
    }
    

    您可以通过 get_type() 来识别哪个孩子。所以,你知道什么时候可以使用 bar()。我不知道什么是最好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-03
      • 2016-06-20
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多