Можно ли когда-либо вызывать нестатический метод-член внутри статического метода-члена в C++?

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

Когда я пробую это в тестовом классе, я получаю следующую ошибку:

"невозможно вызвать функцию-член void TestClass::NonStaticMethod()" без объекта "

6 ответов

Решение

Вы могли бы сделать это с некоторой хитростью. Если вы хотите отслеживать все экземпляры, вы должны зарегистрировать экземпляры во время создания класса. Конечно, это сложно, но вот грубый подход:

class Foo
{
    static std::unordered_set<Foo*> instances;

    void do_it();  // non-static member function

public:
    Foo()
    {
        instances.insert(this);
        // ...
    }

    // add copy constructor, move constructor, etc.

    ~Foo()
    {
        instances.erase(this);
        // ...
    }

    static void call_all()
    {
        for (Foo * p : instances) { p->do_it(); }
    }
};

Вы должны убедиться, что все конструкторы выполняют регистрацию.

Ну, вы можете немного подправить. В основном, храните каждый экземпляр класса в конструкторе. Сейчас я плохо помню C++, поэтому следующий код может не сработать. Я просто пытаюсь дать вам представление о том, что будет работать

class someClass{
static someClass instances[50];
static int count=0;

 void dosomething(){

}

void someClass(){
//Constructor
someClass::instances[someClass::count++]=this;//Store the instance
}

static int theBoss(){
 //This is the static method that calls the non static member.
int ctr=0;
while(ctr<count){                        
instances[ctr++].dosomething();Iterate over the instances and call their non static method
}
}

Да, вы можете вызывать нестатический член из статического члена, и в сообщении об ошибке даже указывается, как это сделать.

Вам необходимо предоставить экземпляр, к которому будет применена нестатическая функция-член:

o.member();

или же

p->member();

То же самое касается доступа к нестатическим переменным-членам:

o.var++;
p->var++;

Если вы делаете это для каждого экземпляра класса, вы должны каким-то образом вести список.

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

#include <iostream>

class A {
public:
    void foo(){std::cerr << "foo\n";}
    static void bar(A &a){ a.foo(); }
    void bar1(){bar(*this); }
};

int main(int argc, char *argv[])
{
    A a;
    A b;
    A::bar(a);
    A::bar(b);
    //OR
    a.bar1();
    b.bar1();
return 0;
}

Единственный раз, когда вы можете законно вызывать нестатическую функцию, это когда у вас есть объект для вызова функции. Так как у вас нет this в статической функции нельзя сказать instanceMethod(); или даже MyClass::instanceMethod();; как-то ты должен сказать obj.instanceMethod(); или же objPtr->instanceMethod();,

Заметьте, однако, что это означает, что если вы создаете объект вашего класса из вашей статической функции (или можете получить ее), вы можете вызывать практически все, что вам нравится. C++ по умолчанию не знает, сколько объектов вы создали определенного типа или где они находятся, поэтому вы должны следить за этим самостоятельно. Одним из способов может быть статический список / массив / карта / набор / любой из объектов, которые вы добавляете в конструктор и удаляете из него в деструкторе.

Другие вопросы по тегам