Singleton pattern: different auto_ptr and unique_ptr behavior

When implementing the factory class, I came across behavior std::auto_ptrthat I cannot understand. I reduced the problem to the next small program, so ... let it begin.

Consider the following singleton class:

singleton.h

#ifndef SINGLETON_H_
#define SINGLETON_H_

#include<iostream>
#include<memory>

class singleton {
public:
  static singleton* get() {
    std::cout << "singleton::get()" << std::endl;
    if ( !ptr_.get() ) {
      std::cout << &ptr_ << std::endl;
      ptr_.reset( new singleton  );
      std::cout << "CREATED" << std::endl;
    }
    return ptr_.get();
  }

  ~singleton(){
    std::cout << "DELETED" << std::endl;
  }
private:
  singleton() {}
  singleton(const singleton&){}

  static std::auto_ptr< singleton > ptr_;
  //static std::unique_ptr< singleton > ptr_;
};

#endif

singleton.cpp

#include<singleton.h>o
std::auto_ptr< singleton > singleton::ptr_(0);
//std::unique_ptr< singleton > singleton::ptr_;

Here, the use of a smart pointer to manage the resource is mainly dictated by the need to avoid leaks when exiting the program. I use this code in the following program:

hijras

#ifndef A_H_
#define A_H_

int foo();

#endif

a.cpp

#include<singleton.h>

namespace {
  singleton * dummy( singleton::get() );
}

int foo() {  
  singleton * pt = singleton::get();
  return 0;
}

main.cpp

#include<a.h>

int main() {

  int a = foo();

  return 0;
}

Now the funny part. I collect three sources separately:

$ g++  -I./ singleton.cpp -c 
$ g++  -I./ a.cpp -c 
$ g++  -I./ main.cpp -c

If I link them explicitly in the following order:

$ g++ main.o singleton.o a.o

everything works as i expect and i get the following: stdout:

singleton::get()
0x804a0d4
CREATED
singleton::get()
DELETED

If I instead link the sources using this order:

$ g++ a.o main.o singleton.o

I get this output:

singleton::get()
0x804a0dc
CREATED
singleton::get()
0x804a0dc
CREATED
DELETED

(Intel GNU) , . , , .

, auto_ptr unique_ptr, , .

: - , ?

+5
2

dummy std::auto_ptr< singleton > singleton::ptr_(0) .

auto_ptr, dummy, singleton::ptr_(0), , dummy, ptr_(0).

ptr_ ptr_(([](){ std::cout << "made ptr_\n"; }(),0)); - .

, unique_ptr, , , - , unique_ptr(0) , , (static , , , unique_ptr(0) , , , ).

- , , :

   static std::auto_ptr< singleton >& get_ptr() {
     static std::auto_ptr< singleton > ptr_(0);
     return ptr_;
   }

ptr_ get_ptr().

+4

, , . , , , , , , . - , a.o singleton.o. singleton.o a.o, singleton::ptr_ dummy, . a.o , dummy, singleton; singleton::ptr_ 0, singleton. foo singleton::get() .

+3

All Articles