是否有可能在C ++中的静态成员方法中调用非静态成员方法?

时间:2012-02-19 04:36:58

标签: c++ static-methods

我怀疑这是可能的,但值得问一下:我想从静态内部调用非静态成员函数。我想为班级的每个当前实例做这件事。有可能吗?

当我在测试类中尝试此操作时,我收到以下错误:

“无法调用成员函数'void TestClass :: NonStaticMethod()'没有对象”

6 个答案:

答案 0 :(得分:5)

你可以用一些技巧来做到这一点。如果要跟踪所有实例,则必须在类构造时注册实例。当然,这很难做到,但这是一个粗略的方法:

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(); }
    }
};

您必须确保所有构造函数都执行注册。

答案 1 :(得分:1)

是的,您可以从静态成员中调用非静态成员,并且错误消息甚至会建议如何。

您需要提供将应用非静态成员函数的实例:

o.member();

p->member();

访问非静态成员变量也是如此:

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

就在课堂的每个实例上进行操作而言,您可以以某种方式保留列表。

答案 2 :(得分:1)

您不能直接调用非静态方法,但如果要在每个当前实例上执行某些操作,可以通过维护静态实例列表并迭代此列表来实现。你的类的构造函数可以将自己添加到这个静态列表中,析构函数可以自行删除。

答案 3 :(得分:1)

嗯,你可以调整一下。基本上在构造函数中存储类的每个实例。现在我不太记得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
}
}

答案 4 :(得分:0)

您有合法调用非静态函数的唯一情况是当您有一个对象来调用该函数时。由于您在静态函数中没有this,因此您无法说instanceMethod();甚至MyClass::instanceMethod();;不知何故,你必须说obj.instanceMethod();objPtr->instanceMethod();

但是,请注意,这意味着如果您从静态函数中创建类的对象(或者可以检索一个),则可以在其上调用任何您喜欢的内容。但是,默认情况下,C ++不会知道您创建的特定类型或对象的对象数量,因此您必须自己跟踪这些对象。一种方法可能是在构造函数中添加静态列表/数组/映射/集合/任何对象,并从析构函数中删除。

答案 5 :(得分:0)

#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;
}