Функции-члены и статические функции со ссылкой на объект

Зачем мне использовать функцию-член, если я могу передать статическую функцию ссылкой на объект?

Например:

#include <iostream>

class Widget{
private:
    int foo;
public:
    Widget(){
        foo = 0;
    }
    static void increment( Widget &w ){
        w.foo++;
        std::cout << w.foo << std::endl;
    }
};

class Gadget{
private:
    int foo;
public:
    Gadget(){
        foo = 0;
    }
    void increment(){
        foo++;
        std::cout << foo << std::endl;
    }
};


int main(int argc, const char * argv[]){

    Widget *w = new Widget();
    Widget::increment( *w );

    Gadget *g = new Gadget();
    g->increment();

    return 0;
}

Это больше, чем стилистическая вещь? Насколько я понимаю, функции-члены создаются для каждого экземпляра объекта, а статические функции - нет, и, поскольку вы можете заставить статические функции работать для каждого экземпляра, как в приведенном выше примере, не должно ли быть немного эффективнее создавать вместо этого статические функции функций-членов?


person zip zop    schedule 12.08.2012    source источник
comment
у вас не может быть виртуальных статических методов.   -  person Raymond Chen    schedule 13.08.2012


Ответы (2)


Мембер-функции не создаются экземпляром. У них есть неявный первый параметр, который является указателем this, поэтому они на самом деле очень похожи на вашу статическую функцию.

Например,

struct Foo {
  void foo(int i) {}
}

Foo f;
f.foo(42);
Foo::foo(f, 42);

две последние строки делают то же самое. Однако трудно понять, как это можно реализовать с помощью статических методов или функций:

struct IFoo {
  virtual foo() const {}
};

struct Foo1 : virtual public IFoo {
  virtual foo() const {}
};

IFoo* f = new Foo1;
f->foo();

Таким образом, помимо синтаксического сахара, позволяющего вам вызывать методы экземпляра с помощью оператора ., они вам нужны для такого рода полиморфизма времени выполнения.

person juanchopanza    schedule 12.08.2012
comment
Да, только локальные переменные относятся к экземпляру при вызове метода. код не дублируется, как говорит juanchopanza. - person Tony; 13.08.2012

Это важно, потому что допускает полиморфизм; особенно потому, что это необходимо для динамической отправки, когда метод, к которому нужно привязать вызов, определяется во время выполнения. по истинному типу объекта, для которого он вызывается. Статический вызов всегда привязывается к методу назначенного типа, независимо от типа времени выполнения самого объекта.

person Will Vousden    schedule 12.08.2012