Podczas implementacji klasy fabrycznej napotkałem zachowanie std::auto_ptr
, którego nie jestem w stanie zrozumieć. Zredukowałem problem do następującego małego programu, więc ... zacznijmy.Wzór Singleton: inne zachowanie auto_ptr i unique_ptr
Rozważmy następującą klasę singleton:
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_;
Tutaj zastosowanie inteligentnego wskaźnika do zarządzania zasobami jest podyktowana głównie przez należy unikać wycieków przy wyjściu z programu. Używam wtedy ten kod w poniższym programie:
A.H
#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;
}
Teraz zabawny część. I skompilować trzy źródła oddzielnie:
$ g++ -I./ singleton.cpp -c
$ g++ -I./ a.cpp -c
$ g++ -I./ main.cpp -c
Gdybym połączyć je wyraźnie w tej kolejności:
$ g++ main.o singleton.o a.o
wszystko działa jak oczekuję, i pojawia się następujący stdout:
singleton::get()
0x804a0d4
CREATED
singleton::get()
DELETED
Jeśli zamiast tego łączę źródła przy użyciu tego zamówienia:
$ g++ a.o main.o singleton.o
uzyskać ten wynik:
singleton::get()
0x804a0dc
CREATED
singleton::get()
0x804a0dc
CREATED
DELETED
Próbowałem różnych marek i kompilatora GNU (Intel) oraz wersje i to zachowanie jest zgodne między nimi. W każdym razie nie widzę kodu, którego zachowanie zależy od kolejności łączenia.
Ponadto, jeśli auto_ptr
zastąpiono przez unique_ptr
, zachowanie jest ZAWSZE zgodne z tym, czego się spodziewam.
To prowadzi mnie do pytania: Czy ktoś ma pojęcia, co się tutaj dzieje?
jaka jest twoja wersja g ++? –
Prawdopodobnie chcesz przeczytać [to pytanie] (http://stackoverflow.com/questions/86582/). – fredoverflow