Можно ли когда-либо вызывать нестатический метод-член внутри статического метода-члена в 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++ по умолчанию не знает, сколько объектов вы создали определенного типа или где они находятся, поэтому вы должны следить за этим самостоятельно. Одним из способов может быть статический список / массив / карта / набор / любой из объектов, которые вы добавляете в конструктор и удаляете из него в деструкторе.