需要确保构造函数/析构函数被调用一次。但“错误:析构函数是私有的”

时间:2012-10-24 06:28:06

标签: c++ singleton virtual-destructor

我有以下代码

#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

原因是,我可以公开构造函数和/或析构函数,并且没有任何错误。但是我需要确保它们都被调用一次且仅一次 怎么样?

3 个答案:

答案 0 :(得分:4)

您的计划中有一些事情:

  1. 您缺少复制构造函数的实现
  2. 您正在复制单件对象
  3. 你的析构函数是私有的(因为你正在复制单例对象,你需要在公共部分中使用析构函数)
  4. 您可以通过不复制对象来解决它:

    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;
    

    };

答案 1 :(得分:1)

非常非常简单。不要将析构函数设为私有!

通过将唯一的构造函数设为私有,确保您的类是单例,也不需要将析构函数设置为私有。

答案 2 :(得分:0)

更好地使用singleton构造函数的这种方法:

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

更多信息的链接是Here