2012-02-19 84 views
0

我怀疑这是可能的,但它值得问:我想从一个静态的内部调用一个非静态成员函数。我想为每个当前的课程实例做。可能吗?是否有可能在C++中调用静态成员方法内的非静态成员方法?

当我尝试这在测试类我得到以下错误:

“不能调用成员函数‘无效的TestClass :: NonStaticMethod()’没有对象”

+3

你为什么要那样做?这是什么类?你是否考虑过一旦你开始谈论“跟踪每一个实例”会失去多大的灵活性?根据多年的专业经验,我几乎可以保证你会后悔这样的决定。 – 2012-02-19 04:47:31

+0

感谢您的建议。我是一名新程序员,事实上,这可能不是我想做的最好的方式。但是,我仍然想知道是否有可能。 – Anthony 2012-02-19 04:50:36

回答

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

你必须确保所有构造进行登记。

+0

为了说明新程序员经常失去的一点,该访问由类型控制,而不是通过'this'指针,我建议将'do_it'私有化。 – 2012-02-19 04:44:25

+0

您还需要处理隐式生成的拷贝构造函数:删除它或使其注册该对象。我想,我会将注册逻辑分解成一个成员或一个基地,以尽量减少多个构造函数的干扰,并避免忘记处理它。 – 2012-02-19 04:45:48

+0

@ BenVoigt:你的意思是访问是每个类而不是每个实例?嗯,也许......这是一个很好的观点。 – 2012-02-19 04:45:55

1

是的,你可以调用来自静态成员内部的非静态成员,并且错误消息甚至建议如何。

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

o.member(); 

p->member(); 

也是一样的访问非静态成员变量:

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

就这个类的每一个实例而言,它取决于你以某种方式保留一个列表。

+2

尽管OP想要为每个当前实例*进行调用。 – 2012-02-19 04:39:11

+0

除了调用静态方法时没有“当前实例”。 – 2012-02-19 04:41:30

+0

@KerrekSB:是的,我在回答问题时看到了这个问题,并且在你评论时正在编辑过程中。为什么人们不能在问题上提出准确的标题? – 2012-02-19 04:41:53

0

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

请注意,这意味着如果您从静态函数中创建类的对象(或者可以检索一个),则可以调用几乎任何您喜欢的对象。尽管C++默认不知道你创建了多少个对象,但是你必须自己跟踪它。一种方法可能是在构造函数中添加一个静态list/array/map/set /对象,并将其从析构函数中移除。

1

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

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 
} 
} 
+0

C++中唯一的文字数字应该是0,1和-1,但从来没有使用过'50':-S – 2012-02-19 04:52:13

+0

自从学校以来从未使用C++,我们只学习了Turbo 3.x版本。从那以后事情发生了变化 – 2012-02-19 05:02:58

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