2012-02-19 98 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; 
} 
相關問題