LINUX.ORG.RU

C++ Command pattern

 ,


0

2

Разбираю Command design pattern по

https://sourcemaking.com/design_patterns/command/cpp/2

Компилирую тамошний код ...

#include <iostream>
#include <string>
using namespace std;

class Person;

class Command
{
    // 1. Create a class that encapsulates an object and a member function
    // a pointer to a member function (the attribute's name is "method")
    Person *object; //    
    void(Person:: *method)();
  public:
    Command(Person *obj = 0, void(Person:: *meth)() = 0)
    {
        object = obj; // the argument's name is "meth"
        method = meth;
    }
    void execute()
    {
        (object-> *method)(); // invoke the method on the object
    }
};

class Person
{
    string name;

    // cmd is a "black box", it is a method invocation
    // promoted to "full object status"
    Command cmd; 
  public:
    Person(string n, Command c): cmd(c)
    {
        name = n;
    }
    void talk()
    {
        // "this" is the sender, cmd has the receiver
        cout << name << " is talking" << endl;
        cmd.execute(); // ask the "black box" to callback the receiver
    }
    void passOn()
    {
        cout << name << " is passing on" << endl;
        
        // 4. When the sender is ready to callback to the receiver,
        // it calls execute()
        cmd.execute(); 
    }
    void gossip()
    {
        cout << name << " is gossiping" << endl;
        cmd.execute();
    }
    void listen()
    {
        cout << name << " is listening" << endl;
    }
};

int main()
{
  // Fred will "execute" Barney which will result in a call to passOn()
  // Barney will "execute" Betty which will result in a call to gossip()
  // Betty will "execute" Wilma which will result in a call to listen()
  Person wilma("Wilma", Command());
  // 2. Instantiate an object for each "callback"
  // 3. Pass each object to its future "sender"
  Person betty("Betty", Command(&wilma, &Person::listen));
  Person barney("Barney", Command(&betty, &Person::gossip));
  Person fred("Fred", Command(&barney, &Person::passOn));
  fred.talk();
} 

... компилятором c++ 5.1.0 из пакета TDM-GCC MinGW . Ответ компилятора

 
$ c++ -c command.cpp
command.cpp: In member function 'void Command::execute()':
command.cpp:21:16: error: invalid use of incomplete type 'class Person'
         (object-> *method)(); // invoke the method on the object
                ^
command.cpp:5:7: note: forward declaration of 'class Person'
 class Person;
       ^
command.cpp:21:19: error: expected unqualified-id before '*' token
         (object-> *method)(); // invoke the method on the object
                   ^

Что не так ?


Там тип ещё неполностью объявлен, надо выносить реализацию метода, в котором тип используется, из объявления класса, вроде такого:

class Person;

class Command
{
    ...
    void execute();
};

class Person {
...
};

void Command::execute()
{
    (object-> *method)(); // invoke the method on the object
}

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Снова ругается

$ c++ command.cpp
command.cpp: In member function 'void Command::execute()':
command.cpp:61:12: error: expected unqualified-id before '*' token
  (object-> *method)(); // invoke the method on the object
            ^

Oaks
() автор топика
Ответ на: комментарий от Oaks

либо (*object).*method(); но тоже без пробела: .* и ->* - это 2 оператора, а не комбинации разыменования и доступа к членам.

http://en.cppreference.com/w/cpp/language/operator_member_access#Built-in_poi...

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.