8

Possible Duplicate:
Cannot access private member in singleton class destructor

I'm implementing a singleton as below.

class A
{
public:

    static A& instance();
private:
    A(void)
    {
        cout << "In the constructor" << endl;
    }
    ~A(void)
    {
        cout << "In the destructor" << endl;
    }

};

A& A::instance()
{
    static A theMainInstance;
    return theMainInstance;
}

int main()
{
    A& a = A::instance();

    return 0;
 }

The destructor is private. Will this get called for the object theMainInstance when the program is about to terminate?

I tried this in Visual studio 6, it gave a compilation error.

"cannot access private member declared in class..."

In visual studio 2010, this got compiled and the destructor was called.

What should be the expectation here according to the standard?

Edit : The confusion arises since Visual Studio 6 behaviour is not so dumb. It can be argued that the constructor of A for the static object is called in the context of a function of A. But the destructor is not called in the context of the same function. This is called from a global context.

Community
  • 1
  • 1
PermanentGuest
  • 5,213
  • 2
  • 27
  • 36
  • My initial thought is that it is fine, since it is created inside of a member function of the same class, but I haven't found the relevant part of the standard yet. – Vaughn Cato Jul 17 '12 at 14:04
  • This example is correct because destructor was called "inside a class" for a static variable
    But for this situation during the compilation causes an error
    http://liveworkspace.org/code/a13eb44e21c01a2b32bd92382722350b
    – Ilya Lavrenov Jul 17 '12 at 14:05
  • 2
    Sounds like Visual Studio standard shenanigans again. If version 6 (6? VS 6?) has that error but VS2010 doesn't, I doubt that it is a language problem, but a compiler problem. – Linuxios Jul 17 '12 at 14:05
  • @stijn : That question discusses a solution to this problem. For me a solution is not what I want. I made the destructor public to avoid it. I'm unclear of the expectation here. – PermanentGuest Jul 17 '12 at 14:09
  • 5
    About MSVC 6.0: 15 years old. Released before Windows XP, ME, Vista. Before iPads, iPhones, before the millenium switch. Long before multicore CPUs, when MMX instructions were the rage and SSE, SSE2, SSE3, SSSE3, SSE4, AVX was not even thought of. 300-400 MHz was much. You had 16 KiB L1 caches. Multi gigabyte harddisks were still new. It was developed before the C++98 standard, which has been superseded two times already, was out. Don't use it. – Sebastian Mach Jul 17 '12 at 14:32
  • @phresnel: Unfortunately it is not my choice :( We (my company) have several number of product-lines with at least more than 100 applications amounting to several millions of codebase, and still selling various versions of them amounting to an income of several billions of euros per year. Unfortunately porting all these to newer technology is not that easy decision for them. – PermanentGuest Jul 17 '12 at 14:42
  • @PermanentGuest For the sake of future visitors to this question, could you explain what "For me a solution is not what I want" means, and what it is you _do_ want? – Mr Lister Jul 17 '12 at 14:43
  • @MrLister: I want to **know** what is right? – PermanentGuest Jul 17 '12 at 14:47
  • 2
    I don't agree that this is an exact duplicate. The question that is listed as a possible duplicate is asking "Why does this not work in VC++6?", while this question is asking "what is the correct behavior and why?". – Vaughn Cato Jul 17 '12 at 15:59
  • I think the compiler will add the destructor to the atexit( ) LIFO stack and call it during program exit. This would happen for static objects with constructors or static primitive with non-compile-time-constant initializer, inside a function. – User 10482 Aug 15 '19 at 19:14

1 Answers1

5

Section 3.6.3.2 of the C++03 standard says:

Destructors for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit.

It doesn't give any restriction regarding having a private destructor, so basically if it gets created it will also get destroyed.

A private destructor does cause a restriction on the ability to declare an object (C++03 12.4.10)

A program is ill-formed if an object of class type or array thereof is declared and the destructor for the class is not accessible at the point of declaration

but since the destructor of A::theMainInstance is accessible at the point of declaration, your example should have no error.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132