1

I have the following code

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

According to many recommendations the destructor is private to be called once only at end of program.
But i have the compiler error:

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

Of cause, I can make constructor and/or destructor public and have no any errors like that. But I need to be sure that both of them are called once and only once.
How?

OlegG
  • 975
  • 3
  • 10
  • 30
  • @alestanis it is a singleton. The `getInstance()` is called `getA()`. – juanchopanza Oct 24 '12 at 06:32
  • 1
    @OlegG Your singleton instance is allocated on the heap (using `new`), but never freed. Why don't you allocate it on the stack? – jogojapan Oct 24 '12 at 06:50
  • There is a question on how to implement the singleton pattern in C++ with many great answers here: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern – jogojapan Oct 24 '12 at 06:51

3 Answers3

4

There are few things in your program :

  1. you are missing implementation of the copy constructor
  2. you are copying the singleton object
  3. your destructor is private (because you are copying the singleton object, you need to have the destructor in the public section)

You can simply resolve it by not copying the objects :

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

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

The singleton should stay a single instance, therefore (as suggested) the best approach would be to delete copy and move constructors.


Since you need the constructor and destructor called only once, then you need to use meyers singleton. That means changing your function to this :

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

};

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • 2
    Making the copy constructor and assignment operator private would also help. – juanchopanza Oct 24 '12 at 06:34
  • There is one more issue with the code in the question: The singleton instance is allocated on the heap, but never freed. – jogojapan Oct 24 '12 at 06:47
  • @jogojapan That's the idea. It is freed when the program ends. It all depends on what kind of singleton you need. – BЈовић Oct 24 '12 at 06:57
  • @BЈовић What do you mean it is freed when the program ends? The OS will remove the process and free all the memory it used, but that is hardly the right way to release memory. The destructor will never be called that way. – jogojapan Oct 24 '12 at 07:02
1

Very, very simple. Don't make the destructor private!

By making the only constructor private you ensure that your class is a singleton, there is no need to make the destructor private as well.

john
  • 85,011
  • 4
  • 57
  • 81
  • That doesn't really answer the (hidden) question of "how to create a singleton" – alestanis Oct 24 '12 at 06:31
  • @alestanis, well go for it, show him how. There are of course many ways to make a singleton, the best tutorial I ever read was in the book *Modern C++ Design* by Andrei Alexandrescu. I don't feel like repeating all of that. – john Oct 24 '12 at 06:34
  • You need to make the copy constructor private as well, if you intend to make it a singleton and enforce it w/o a private destructor. – bdonlan Oct 24 '12 at 06:35
  • @john: If I do dtor public it is able to be called more that once. It is inappropriate! – OlegG Oct 24 '12 at 06:35
  • @OlegG I missed that you are copying the 'singleton' in your main function. Obviously you cannot copy a singleton. Maybe you do need a tutorial on writing singletons. Other answers to your question will give you a better idea than mine. – john Oct 24 '12 at 06:41
  • @OlegG the solution is to disallow copying and assignment. You can also simplify the problem by avoiding dynamic allocation. See my answer. – juanchopanza Oct 24 '12 at 06:58
0

Better use this method of singleton constructor:

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

Link for more info is Here

Denis Ermolin
  • 5,530
  • 6
  • 27
  • 44