Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#define PROTO_IFACE(D_iface, D_an) \
template<> void anFill<D_iface>(An<D_iface>& D_an)// test1.h
void f() {}
// test2.h
inline void f() {}
// test3.h
template<class T>
void f() {}// .h
class X
{
void f();
}
inline void X::f() {...} // cannot be "static"
class X
{
static void f();
};class X
{
void f();
};
static void X::f() {} // compilation error !
inline void X::f() {} // OK
template<typename T>
T& single()
{
static T t;
return t;
}struct A {};
void foo() { static A a; };
struct B {
~B() { foo(); };
};
void main() {
static B b;
foo();
};
#include "stdafx.h"
#include <iostream>
#include <Singleton.h>
template< class T >
struct An
{
typedef Loki::SingletonHolder< T > TSingleton;
An(){ TSingleton::Instance(); }
T &operator*(){ return TSingleton::Instance(); }
T *operator->(){ return &TSingleton::Instance(); }
};
struct A
{
A(){ std::cout << "A" << std::endl; a = 1; }
~A(){ std::cout << "~A" << std::endl; a = -1; }
int a;
};
struct B
{
An< A > pa;
B(){ std::cout << "B" << std::endl; }
~B(){ std::cout << "~B" << std::endl; out(); }
void out(){ std::cout << pa->a << std::endl; }
};
int _tmain( int, _TCHAR*[] )
{
An< B > pb;
pb->out();
return 0;
}
#include "stdafx.h"
#include <iostream>
#include <memory>
// Loki::CreateUsingNew with abstract classes support.
template< class T, class I = T >
struct CreateUsingNew
{
static I* Create(){ return new T; }
static void Destroy( I* p ){ delete static_cast< T * >( p ); }
};
// Use CreateUsingNew< T > as the default creation strategy.
template< class T >
struct SelectCreationStrategy
: CreateUsingNew< T >
{
};
template< class T, template< class > class TCreationStrategy = SelectCreationStrategy >
class An
{
std::shared_ptr< T > _guard;
T &get()
{
static std::shared_ptr< T > p( TCreationStrategy< T >::Create(), &TCreationStrategy< T >::Destroy );
_guard = p;
return *p;
}
public:
T &operator*(){ return get(); }
T *operator->(){ return &get(); }
};
// Note: usage of this singleton is the same as in the previous variate, no macro, etc.
struct A
{
A(){ std::cout << "A" << std::endl; a = 1; }
~A(){ std::cout << "~A" << std::endl; a = -1; }
int a;
};
// Abstract
struct B
{
B(){ std::cout << "B" << std::endl; }
~B(){ std::cout << "~B" << std::endl; }
virtual void out() = 0;
};
// Impl
struct C : B
{
An< A > pa;
C(){ std::cout << "C" << std::endl; }
~C(){ std::cout << "~C" << std::endl; out(); }
virtual void out(){ std::cout << pa->a << std::endl; }
};
// Overridden creation strategy for B.
// Note: you can use even custom allocators here.
template<>
struct SelectCreationStrategy< B >
: CreateUsingNew< C, B >
{
};
int _tmain( int, _TCHAR*[] )
{
An< B > pb;
pb->out();
return 0;
}
template<>
struct SelectCreationStrategy< D >
: CreateUsingNew< D, B >
{
};
template<>
struct SelectCreationStrategy< D >
{
static B* Create(){ return new D( /* something */ ); }
static void Destroy( B* p ){ delete static_cast< D * >( p ); }
};
Будем использовать умный указатель из стандартной библиотеки std::shared_ptr заголовочного файла memory. Стоит отметить, что такой класс доступен для современных компиляторов, которые поддерживают стандарт C++0x. Для тех, кто использует старый компилятор, можно использовать boost::shared_ptr.
sveolon@sveolon-laptop ~/build/tmp $ cat ./main.cpp
#include <tr1/memory>
#include int main()
{
std::tr1::shared_ptr p (new int(3));
std::cout << *p << std::endl;
return 0;
}
sveolon@sveolon-laptop ~/build/tmp $ g++ ./main.cpp
sveolon@sveolon-laptop ~/build/tmp $ ./a.out
3
sveolon@sveolon-laptop ~/build/tmp $ g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright © 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sveolon@sveolon-laptop ~/build/tmp $
Синглтон и время жизни объекта