Можете ли вы объединить методы, возвращая указатель на их объект? - PullRequest
2 голосов
/ 25 октября 2009

Моя цель - разрешить цепочку таких методов, как:

class Foo;
Foo f;
f.setX(12).setY(90);

Возможно ли, чтобы методы Foo возвращали указатель на свой экземпляр, разрешая такую ​​цепочку?

Ответы [ 5 ]

10 голосов
/ 25 октября 2009

Для этого конкретного синтаксиса вы должны вернуть ссылку

class Foo {
public:

  Foo& SetX(int x) {
    /* whatever */
    return *this;
  } 

  Foo& SetY(int y) {
    /* whatever */
    return *this;
  } 
};

P.S. Или вы можете вернуть копию (Foo вместо Foo&). Невозможно сказать, что вам нужно, без более подробной информации, но, судя по названию функции (Set...), которое вы использовали в своем примере, вам, вероятно, понадобится ссылочный тип возврата.

4 голосов
/ 25 октября 2009

Другим примером является идиома именованных параметров .

3 голосов
/ 25 октября 2009

Да, это возможно. Типичным примером является перегрузка операторов, например operator + = ().

Например, если у вас есть класс с именем ComplexNumber, и вы хотите сделать что-то вроде a + = b, тогда вы можете

ComplexNumber& operator+=(ComplexNumber& other){
     //add here
     return *this; 
}

В вашем случае вы можете использовать.

Foo& setX(int x){
//yada yada yada
return *this;
}
2 голосов
/ 25 октября 2009

Ну, вы можете вернуть объект из его собственной функции, чтобы объединить функции в цепочку:

#include <iostream>
class foo
{
    public:
        foo() {num = 0;}
        // Returning a `foo` creates a new copy of the object each time...
        // So returning a `foo&` returns a *reference* to this, and operates on
        // the *same* object each time.
        foo& Add(int n)  
        {
            num += n;
            std::cout << num << std::endl;
            // If you actually DO need a pointer, 
            // change the return type and do not dereference `this`
            return *this;  
        }
    private:
        int num;
};

int main()
{
    foo f;
    f.Add(10).Add(5).Add(3);
    return 0;
}

Какие выходы:

$ ./a.out
10
15
18
0 голосов
/ 25 октября 2009
#include <iostream>

using namespace::std;

class Print
{
    public:
        Print * hello();
        Print * goodbye();
        Print * newLine();
};

Print * Print::hello()
{
    cout << "Hello";
    return this;
}
Print * Print::goodbye()
{
    cout << "Goodbye";
    return this;
}
Print * Print::newLine()
{
    cout << endl;
    return this;
}

int main (void)
{
    Print print;
    print.hello()->newLine()->goodbye()->newLine();

    return 0;
}

Выход:

   Hello
   Goodbye
...