在C++中实现接口的问题

Problems with implementing Interfaces in C++

本文关键字:问题 接口 实现 C++      更新时间:2023-10-16

我正在尝试用C++学习设计模式。我正在执行OReilly's Head First Design Patterns第一章中关于Duck问题给出的程序。请耐心听我说,这是一个很长的问题。

无论如何,我已经尝试创建以下2个接口:

class QuackBehavior
{
public:
    virtual void quack() = 0 ;
};
class FlyBehavior
{
public:
    virtual void fly() = 0 ;
};

现在我有一个Duck类,它需要有上面两个类的实例。我正在做的是:

class Duck
{
public:
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    Duck()
    {
    }
    virtual void display() = 0 ;
    void performQuack()
    {
        quackBehavior.quack() ;
    }
    void performFly()
    {
        flyBehavior.fly() ;
    }
    void swim()
    {
        std::cout << "All ducks swim!n" ;
    }
};

我还创建了实现接口的类:

class Quack: public QuackBehavior
{
    void quack()
    {
        std::cout << "QUACK!n" ;
    }
};
class FlyWithWings: public FlyBehavior
{
    void fly()
    {
        std::cout << "I'm flying...n" ;
    }
};

同样。我创建了一个继承Duck类和我的主要方法的类:

class MallardDuck: public Duck
{
public:
    MallardDuck()
    {
        quackBehavior = new Quack() ;
        flyBehavior = new FlyWithWings() ;
    }
    void display()
    {
        std::cout << "I'm a real duckn" ;
    }
};
int main(int argc, char const *argv[])
{
    Duck mallard = new MallardDuck() ;
    mallard.performFly() ;
    mallard.performQuack() ;
    return 0;
}

然而,当我编译程序时,我会得到一长串错误。有人能帮我吗?提前感谢那些真正阅读了完整问题的人。

FlyBehavior/QuackBehavior是抽象类,不能使它们成为Duck的成员,必须使用指针(动态多态性通过引用或指针进行调度):

#include <memory>
class Duck
{
public:
    std::unique<FlyBehavior> flyBehavior;
    std::unique<QuackBehavior> quackBehavior;
//...
};

MallardDuck() : flyBehavior( new FlyWithWings()), quackBehavior(new Quack()) 
{ }

由于FlyBehavior/QuackBehavior充当抽象类,所以应该使它们的析构函数成为虚拟的。

class QuackBehavior
{
public:
    virtual void quack() = 0 ;
    virutal ~QuackBehavior() {}
};
class FlyBehavior
{
public:
    virtual void fly() = 0 ;
    virtual ~FlyBehavior() {}
};

不要忘记实现纯虚拟方法:

virtual void quack() = 0 ;

 

当你正常声明一个对象时,你不能用new来声明它。当你把它声明为指针时,你必须用->来调用它的项。

QuackBehavior quackBehavior;
quackBehavior = new Quack() ;  // <------- ERROR, quackBehavior is not a pointer

Duck mallard = new MallardDuck(); // <------- ERROR, mallard is not a pointer
mallard.performFly() ; // <-------- ERROR, you must use -> instead of .
                       //           if mallard is a pointer

最后,使用以下代码:

class MallardDuck: public Duck
{
public:
    MallardDuck()
    {
    }
    void display()
    {
        std::cout << "I'm a real duckn" ;
    }
};
int main(int argc, char const *argv[])
{
    Duck *mallard = new MallardDuck() ;
    mallard->performFly() ;
    mallard->performQuack() ;
    ...
    delete mallard;
}

您正在学习C++,在理解了指针之后,最好知道并使用智能指针(std::unique_ptrstd::shared_ptr)而不是裸指针。

不能有抽象类的实例。Duck中应该有指向基类的指针,而不是对象,否则会出现编译错误。

从这些电话中也可以明显看出:

quackBehavior = new Quack();
flyBehavior = new FlyWithWings(); 

CCD_ 10和CCD_。

在类Duck中,抽象类成员对象flyBehaviorquackBehavior需要在构造函数中实例化它们的派生类FlyWithWingsQuack,同时成员需要是指针类型才能使用这样的继承方案:

class Duck
{
public:
    FlyBehavior* flyBehavior;
    QuackBehavior* quackBehavior;
    Duck()
    {
          flyBehavior = new FlyWithWings();
          quackBehavior = new Quack();
    }
    ~Duck()
    {
          delete flyBehavior;
          delete quackBehavior;
    }
    virtual void display() = 0 ;
    void performQuack()
    {
        quackBehavior.quack() ;
    }
    void performFly()
    {
        flyBehavior.fly() ;
    }
    void swim()
    {
        std::cout << "All ducks swim!n" ;
    }
};

您还需要基类中的虚拟析构函数:

class QuackBehavior
{
public:
    virtual void quack() = 0 ;
    virtual ~QuackBehavior();
};
class FlyBehavior
{
public:
    virtual void fly() = 0 ;
    virtual ~FlyBehavior();
};

通过将函数声明为纯虚拟函数,如下所示:

virtual void display() = 0 ;

,你实际上是在使它所属的类抽象化。抽象意味着它永远无法实例化。您永远不能创建抽象类类型的实例。如果你想拥有Duck对象,就去掉=0。