Re: duct typing and interface in C++
 
TP wrote:
Hello,
I convert a Python/Qt program (PyQt) in C++/Qt.
The programmer has used the duck typing of Python, thus I would like to have
duck typing in C++, in fact exactly what is described in the "best answer"
at the following address:
http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
the-old-variant-type-and-or-interfaces
(the "best answer" is the second post of the page, the one with a green
sign).
Is it possible in C++?
Thanks in advance,
TP
I've tried just for fun. This is probably a naive
imitation... I just used codepad therefore had
no other libraries (e.g. boost available).
Output:
Duffy quacked!
Donald quacked!
//code...
#include <iostream>
#include <algorithm>
class Duck
{
     struct QuackIF
     {
       virtual void quack() = 0;
       virtual QuackIF* clone() const = 0;
       virtual ~QuackIF(){}
     };
     template <class T>
     struct QuackImpl : QuackIF
     {
       typedef void (T::*QuackFunc)();
       QuackImpl( T& receiver )
       : receiver_( &receiver ),
         f_( &T::quack )
       {
       }
       virtual QuackIF* clone() const
       {
         return new QuackImpl( *this );
       }
       virtual void quack()
       {
         (receiver_->*f_)();//Quack!!!
       }
       virtual ~QuackImpl(){}
       private:
         T* receiver_;
         QuackFunc f_;
     };
     QuackIF* duck_;
     public:
       Duck( const Duck& other )
       : duck_( other.duck_ ? other.duck_->clone() : 0 )
       {
       }
       ~Duck(){ delete duck_; }
       Duck& operator=( Duck other )
       {
         std::swap( other.duck_, duck_ ); return *this;
       }
       template <class DuckT>
       Duck( DuckT* duck )
       : duck_( new QuackImpl<DuckT>( *duck ) )
       {
       }
       void quack()
       {
         if( duck_ ){ duck_->quack(); }
         else
         {
           std::cout << "Quack!" << std::endl;
         }
       }
};
struct Daffy
{
   void quack(){ std::cout << "Duffy quacked!" << std::endl; }
};
struct Donald
{
   void quack(){ std::cout << "Donald quacked!" << std::endl; }
};
int main()
{
   Duck duck = new Daffy;
   duck.quack();
   duck = new Donald;
   duck.quack();
}