2016-11-21 149 views
1

我遇到的代碼來了,如同下面,這基本上是我們使類的構造私人和提供一個靜態公共函數創建一個單獨的類的實例的私有成員函數(構造函數)需要時的課程實例。如何靜態函數訪問類

我的問題是當我們調用new運算符在靜態函數中創建單例類的對象時,那麼該類的構造函數肯定會被調用。我很困惑它是如何發生的,因爲據我所知,一個靜態函數只能訪問一個類的靜態成員和靜態函數。那麼如何訪問一個類的私有函數(構造函數)呢?

靜態函數可以調用類的任何私人或公共成員函數不會造成任何實例?

#include <iostream> 

using namespace std; 

class Singleton 
{ 
public: 
    static Singleton *getInstance(); 

private: 
    Singleton(){} 
    static Singleton* instance; 
}; 

Singleton* Singleton::instance = 0; 
Singleton* Singleton::getInstance() 
{ 
    if(!instance) { 
     instance = new Singleton(); //private ctor will be called 
     cout << "getInstance(): First instance\n"; 
     return instance; 
    } 
    else { 
     cout << "getInstance(): previous instance\n"; 
     return instance; 
    } 
} 

int main() 
{ 
    Singleton *s1 = Singleton::getInstance(); 
    Singleton *s2 = Singleton::getInstance(); 
    return 0; 
} 

但是,當我寫了如下示例代碼:

class Sample 
{ 
    private: 
     void testFunc() 
     { 
      std::cout << "Inside private function" <<std::endl; 
     } 
    public: 
     static void statFunc() 
     { 
      std::cout << "Inside static function" <<std::endl; 
      testFunc(); 
     } 
}; 

int main() 
{ 
    Sample::statFunc(); 

    return 0; 
} 

我與G ++編譯錯誤:

file.cpp: In static member function ‘static void Sample::statFunc()’: 
file.cpp:61: error: cannot call member function ‘void Sample::testFunc()’ without object. 

如果我們可以用靜態公網訪問類的私有函數函數那麼爲什麼我得到這個錯誤?

+0

簡答:恕我直言,是的。恕我直言,你的代碼沒有問題。 'getInstance'是'Singleton'類的成員,因此它可以調用該類的所有方法,甚至是私有方法。 –

回答

0

上面的代碼工作的原因是因爲getInstance()的實現調用不requrire對象實例的構造函數。

靜態成員函數屬於類不是對象。因此,在調用靜態成員函數時沒有對象的實例,因爲不存在指針,所以不能訪問this指針。如果要從靜態函數訪問非靜態私有成員函數,則需要將該對象的引用傳遞給該函數。例如

例如

class foo { 
    public: 
      foo(int i) : myInt(i) {} 
      static int myStaticMethod(foo & obj); 
    private: 
      int myInt; 
    }; 

    int foo::myStaticMethod(foo & obj) { 
      return obj.myInt; 
    } 

#include <iostream> 


int main() { 
foo f(1); 
std::cout << foo::myStaticMethod(f); 
return 0; 
}; 
+0

感謝您的回答。所以我從上面的理解是,因爲ctor是一個特殊的成員函數,它不需要任何對象被調用,所以它可以使用靜態函數(沒有任何對象)來調用,但其他類的普通成員函數需要類實例爲了調用它們,所以它們不能在沒有對象的靜態函數內被調用。 – Viki

+0

是啊 – TomJ

1

靜態函數可以調用類的任何私人或公共成員函數不會造成任何實例?

創建一個實例。

instance = new Singleton(); 

new關鍵字創建Singleton對象。

而且,是的,因爲Singleton::getInstance是該類的成員函數,所以它有能力調用構造函數(儘管注意你只是間接地這樣做),不管它是否爲static

0

回答你問題的第二部分,您已經後來又說:

class Sample 
{ 
private: 
    void testFunc() 
    { 
    std::cout << "Inside private function" << std::endl; 
    } 
public: 
    static void statFunc() 
    { 
    std::cout << "Inside static function" << std::endl; 

    Sample s; 
    s.testFunc();   // this is OK, there is an object (s) and we call 
          // testFunc upon s 

    // testFunc();   // this is not OK, there is no object 
    } 
    void InstanceFunction() 
    { 
    std::cout << "Inside public instance function" << std::endl; 
    testFunc(); 
    } 
}; 


int main() 
{ 
    Sample s; 
    s.InstanceFunction(); 

    Sample::statFunc(); 
    return 0; 
} 

調用從內statFunctestFunc();不能做,因爲testFunc(私人或不)是一個實例功能,你需要一個Sample反對說testFunc可根據操作,但是statFuncstatic功能,因此沒有Sample對象。

錯誤信息很清楚。

僅當您提供對象時才能從statFunc調用testFunc,請參閱上面的代碼。

+0

我認爲,以類似的方式,單例類的構造函數是一個類函數,不應該被靜態函數調用。如果構造函數可以在靜態函數內部調用,那麼爲什麼不是正常的私有函數會讓我困惑呢? – Viki

+0

@Vikram記得,構造函數不是一個普通的成員函數。當你寫'instance = new Singleton();'你創建一個對象時,他的構造函數被調用到正在創建的對象上。 –

+0

@Vikram,我編輯了答案,現在有一個例子,你可以從'statFunc'內調用'testFunc'。 –