2010-10-08 40 views
1

Im OOP編程新技術,C++和Im目前正在學習設計模式。如何將Java接口代碼移植到C++抽象基類中?

只需抓住Head First Design Patterns書籍即可學習。它其實很棒,而且我已經掌握了基本概念。第一章談論編程到接口而不是實現。不幸的是,對我來說,這些例子使用java。

下面是使用「接口」的書中的java代碼示例,我明白這不能直接在C++中移植。我試圖實現C++的抽象基類。但是Im特別在動態設置QuackBehavior時丟失了。

C++虛擬函數定義可以動態嗎?有人可以告訴我如何以最佳方式將此Java代碼移植到C++中嗎?我需要這個來確保即時通訊在學習面向對象的正確軌道上。謝謝!

//FlyBehavior.java 
public interface FlyBehavior{ 
    public void fly(); //the interface that all flying behavior classes implement 
} 


public class FlyWithWings implements FlyBehavior { 
    public void fly(){ 
     System.out.println("Im flying!"); //flying behavior implementation for ducks that do fly 
    } 
} 

//QuackBehavior.java 
public interface QuackBehavior{ 
    public void quack(); 
} 

public class Quack implements QuackBehavior { 
    public void quack() { 
     System.out.println("Quack"); 
    } 
} 

public class Squeak implements QuackBehavior { 
    public void quack() { 
     System.out.println("Squeak"); 
    } 
} 

public class MuteQuack implements QuackBehavior { 
    public void quack() { 
     System.out.println("<<SILENCE>>"); 
    } 
} 



//duck.java 
public abstract class Duck{ 
    FlyBehavior flyBehavior; 
    QuackBehavior quackBehavior; 
    public Duck(){ 
    } 

    public abstract void display(); 

    public void performFly(){ 
     flyBehavior.fly(); 
    } 

    public void performQuack(){ 
     quackBehavior.quack(); 
    } 

    public void setFlyBehavior(FlyBehavior fb){ 
     flyBehavior = fb; 
    } 

    public void setQuackBehavior(QuackBehavior qb){ 
     quackBehavior = qb; 
    } 

    public void swim(){ 
     System.out.println ("All duck float, even decoys"); 
    } 
} 


//MallardDuck.java 
public class MallardDuck extends Duck{ 
    public MallardDuck(){ 
     quackBehavior = new Quack(); 
     flyBehavior = new FlyWithWings(); 
    } 

    public void display(){ 
     System.out.println("Im a real Mallard duck"); 
    } 
} 

//miniducksim.java 
public class MiniDuckSimulator{ 
    public static void main (String[] args){ 
     Duck mallard = new MallardDuck(); 

     mallard.setQuackBehavior(new Squeak()); // this is where im lost 
               //how can definition of a virtual functions in C++ be dynamic? 

     mallard.performQuack(); 
     mallard.performFly(); 
    } 
} 
+0

嘿 - 我也喜歡那本書,我只是假設它可以用抽象類來完成。你能發佈迄今爲止所做的代碼嗎?似乎它*應該*是可能的。 – Jeff 2010-10-08 04:39:01

+0

我得到你的問題,但我想知道你在這種情況下對'動態'的定義是什麼? – birryree 2010-10-08 04:41:52

+1

'如何定義C++中的虛函數?' 然後,什麼是虛函數?這些確實是動態的。 – Hemant 2010-10-08 04:42:07

回答

1

當 - 應該知道頭第一個幫會將它移走。反正這裏有一個解決方案:

// HeadFirst.cpp : Defines the entry point for the console application. 
    // 

    #include "stdafx.h" 

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

    class Quack : public QuackBehavior 
    { 
    public: 
     void quack() 
     { 
     printf("Quack"); 
     } 
    }; 

    class Squeak : public QuackBehavior 
    { 
    public: 
     void quack() 
     { 
     printf("Squeak"); 
     } 
    }; 

    class Duck 
    { 
    public: 
     QuackBehavior *pQuack; 

     void performQuack() 
     { 
     if (pQuack!=NULL) 
      pQuack->quack(); 
     } 

     void setQuackBehavior(QuackBehavior *qb) 
     { 
     pQuack = qb; 
     } 
    }; 

    class MallardDuck : public Duck 
    { 
    public: 
     MallardDuck() 
     { 
     pQuack = new Quack(); 
     } 
    }; 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 
     Duck *mallard = new MallardDuck(); 
     mallard->setQuackBehavior(new Squeak()); 
     mallard->performQuack(); 
    return 0; 
    } 
+0

正是我在找什麼。謝謝。 – ginotria 2010-10-08 05:17:42

1

如果Quack()方法聲明爲純粹的抽象基類QuackBehavior虛,那麼事情應該罰款。

在方法SetQuackBehavior()中預計有一個基類引用,它顯然可以容納它的任何派生類對象。在C++中可以應用相同的方法,使用SetQuackBehavior()方法中指向QuackBehavior類的指針,然後將Squeak類對象的地址傳遞給它。現在,當通過基類指針在PerformQuack()中調用quack()方法時,它將在這種情況下調用派生類的適當具體方法,即Squeak

+0

明白了!謝謝! – ginotria 2010-10-08 05:10:52

+0

很高興,我可以幫助... :) – Hemant 2010-10-08 05:16:02

0

這裏有一個粗糙翻譯 - 只是警告說,這並不打我的習慣(或好)使用C++:

#include <iostream> 

struct FlyBehavior { 
    virtual void operator()() const = 0; 
}; 

struct FlyWithWings: FlyBehavior { 
    virtual void operator()() const { std::cout << "I'm flying!\n"; } 
}; 

struct QuackBehavior { 
    virtual void operator()() const = 0; 
}; 

struct Quack : QuackBehavior { 
    virtual void operator()() const { std::cout << "Quack\n"; } 
}; 

struct Squeak : QuackBehavior { 
    virtual void operator()() const { std::cout << "Squeak\n"; } 
}; 

struct MuteQuack : QuackBehavior { 
    virtual void operator()() const { std::cout << ("<<SILENCE>>\n"); } 
}; 

class Duck { 
    FlyBehavior const *flyBehavior; 
    QuackBehavior const *quackBehavior; 
public: 
    Duck(FlyBehavior const *f, QuackBehavior const *q) : 
     flyBehavior(f), quackBehavior(q) 
    {} 

    void setQuackBehavior(QuackBehavior *q) { quackBehavior = q; } 
    void setFlyBehavior(FlyBehavior *f) { flyBehavior = f; } 
    virtual void display() const = 0; 
    void fly() const { (*flyBehavior)(); } 
    void quack() const { (*quackBehavior)(); } 
    void swim() const { std::cout << "All ducks float, even decoys\n"; } 
}; 

struct MallardDuck : Duck { 
    MallardDuck() : Duck(&FlyWithWings(), &Quack()) { } 
    virtual void display() const { std::cout << "I'm a real Mallard duck\n"; } 
}; 

int main() { 
    MallardDuck mallard; 
    mallard.setQuackBehavior(&Squeak()); 
    mallard.quack(); 
    mallard.fly(); 
    return 0; 
}