2012-10-24 172 views
1

我有以下代碼需要確保構造函數/析構函數被調用一次。但「錯誤:析構函數是私有的」

#include <vector> 
#include <iostream> 

class A{ 
    private: 
    std::vector<int> x; 
    A(){ 
     // here is a code to open and initialize several devices 
     // it is allowed to be called once only!!! 
     std::cout << "constructor called" << std::endl; 
    }; 

    virtual ~A(){ 
     // here is a code to close several devices 
     // it is allowed to be called once only!!! 
     std::cout << "destructor called" << std::endl; 
    }; 


    public: 
    static A & getA(){ 
     static A* singleton = new A; 
     std::cout << "singleton got" << std::endl; 
     return *singleton; 
    }; 

}; 


int main(int argc, char** argv){ 

    A a = A::getA(); 

    return(0); 
} 

根據許多建議析構函數是私有的一次只在程序結束時被調用。
但我有編譯器錯誤:

Test.cpp: In function 'int main(int, char**)': 
Test.cpp:12:10: error: 'virtual A::~A()' is private 
Test.cpp:29:19: error: within this context 
Test.cpp:12:10: error: 'virtual A::~A()' is private 
Test.cpp:29:19: error: within this context 

事業,我可以構造和/或析構函數的公共和沒有類似的錯誤。但是我需要確定他們兩次只被調用過一次。
如何?

+0

@alestanis它是一個單例。 'getInstance()'被稱爲'getA()'。 – juanchopanza

+1

@OlegG你的單例實例在堆上分配(使用'new'),但從未釋放。你爲什麼不把它分配給堆棧? – jogojapan

+0

有一個關於如何在C++中實現單例模式的問題,在這裏有很多很好的答案:http://stackoverflow.com/questions/1008019/c-singleton-design-pattern – jogojapan

回答

0

更好地利用單構造的這種方法:

static A* getA(){ 
    static A singleton; 
    std::cout << "singleton got" << std::endl; 
    return &singleton; 
}; 

鏈接獲取更多信息是Here

+2

這是一個很好的建議,雖然很難看出它是如何回答這個問題的! – juanchopanza

+0

對於downvoters,請你的建議。 –

+0

可能與我之前的評論有關:它不回答問題或解決OP代碼的基本問題。 – juanchopanza

1

非常非常簡單。不要讓析構函數爲私有!

通過使唯一的構造函數爲私有的,確保您的類是單例,不需要使析構函數也是私有的。

+0

這並沒有真正回答(隱藏) 「如何創建一個單身人士」的問題 – alestanis

+0

@alestanis,順其自然,向他展示如何。當然,有很多方法可以製作一個單身人士,我讀過的最好的教程是在Andrei Alexandrescu的書* Modern C++ Design *中。我不想重複所有這些。 – john

+0

如果您打算將其構建爲單例並將其強制執行而不使用私有析構函數,則還需要將複製構造函數設爲私有。 – bdonlan

4

有在你的程序幾件事情:

  1. 你缺少執行拷貝構造函數
  2. 您要複製單個對象
  3. 您的析構函數是私有的(因爲要複製的單一對象的,你需要在公共部分有拆分器)

你可以簡單地通過不復制對象來解決它:

int main(int argc, char** argv){ 

    A &a = A::getA(); 
} 

單身人士應該保持一個單一的實例,因此(建議)最好的辦法是刪除複製和移動構造函數。


由於需要構造和析構函數只調用一次,那麼你需要使用meyers singleton。這意味着將您的功能更改爲:

static A & getA(){ 
    static A singleton; 
    std::cout << "singleton got" << std::endl; 
    return singleton; 

};

+2

使複製構造函數和賦值運算符私人也將有所幫助。 – juanchopanza

+0

問題中的代碼還有一個問題:單例實例分配在堆上,但從未釋放。 – jogojapan

+0

@jogojapan這就是主意。當程序結束時它被釋放。這一切都取決於你需要什麼樣的單例。 –

相關問題