在C+中实现接口的问题+; 我试图用C++学习设计模式。我正在实施《OReilly的头优先设计模式》第一章中关于鸭子问题的程序。请容忍我,这是一个很长的问题

在C+中实现接口的问题+; 我试图用C++学习设计模式。我正在实施《OReilly的头优先设计模式》第一章中关于鸭子问题的程序。请容忍我,这是一个很长的问题,c++,design-patterns,inheritance,pure-virtual,C++,Design Patterns,Inheritance,Pure Virtual,无论如何,我已经尝试创建了以下两个接口: class QuackBehavior { public: virtual void quack() = 0 ; }; class FlyBehavior { public: virtual void fly() = 0 ; }; class Quack: public QuackBehavior { void quack() { std::cout << "QUACK!\n" ;

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

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

class FlyBehavior
{
public:
    virtual void fly() = 0 ;
};
class Quack: public QuackBehavior
{
    void quack()
    {
        std::cout << "QUACK!\n" ;
    }
};

class FlyWithWings: public FlyBehavior
{
    void fly()
    {
        std::cout << "I'm flying...\n" ;
    }
};
现在我有一个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-Duck
{
公众:
飞行行为;
怪癖行为怪癖行为;
鸭子()
{
}
虚空显示()=0;
void performQuack()
{
嘎嘎的行为;
}
性能无效()
{
flyBehavior.fly();
}
无效游泳()
{

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

从这些呼吁中也可以明显看出:

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

new-Quack()
new-FlyWithWings()
都是返回指针。

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


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

virtual void quack() = 0 ;

当您正常地声明一个对象时,您不能
new
它。当您将它声明为指针时,您必须通过
->
调用它的项

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

quackBehavior=new Quack();//将函数声明为纯虚拟函数,如下所示:

virtual void display() = 0 ;

,您正在有效地将它所属的类抽象化。抽象意味着它永远不能被实例化。您永远不能创建抽象类类型的实例。如果您想拥有Duck对象,请去掉=0。

在类
Duck
中,抽象类成员对象
flyBehavior
quackBehavior
需要在构造函数中使用其派生类
FlyWithWings
Quack
进行实例化,同时成员需要为类型指针才能使用此类继承方案:

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" ;
    }
};

我想说,如果他只是学习C++,他最好不要使用智能指针。他必须学习指针在某个点上的实际工作。如果他先使用拐杖,他会更好地理解它们,然后再使用可应用的智能指针。他还可以更好地理解智能点。rs可以工作,但不起作用,并且比他根本不练习使用普通指针更具局限性。是的,我已经在我的类中实现了纯虚拟函数。代码现在运行良好。这是帮助我理解概念的绝佳方式!:)实际上我不想初始化
flyBehavior
quackBeh在
Duck
类中使用avior
。我想在
MallardDuck
类中初始化它们。你到底为什么建议对不懂原始指针的人使用智能指针?@icepack:因为这样可以避免触及指针的所有细微之处。关于如何教授C++有两种思想流派:一种是作为一种全新的语言,全新的语言学校很早就使用了标准库,后来又深入到了最深的角落。
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 duck\n" ;
    }
};

int main(int argc, char const *argv[])
{
    Duck *mallard = new MallardDuck() ;
    mallard->performFly() ;
    mallard->performQuack() ;

    ...

    delete mallard;
}
virtual void display() = 0 ;
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();

};