Файл shptr.hpp


Подробное описание

Класс умного указателя на сериализуемый объект.

#include <memory>
#include <oess_1/defs/h/ex.hpp>
#include <oess_1/stdsn/h/declspec.hpp>
#include <oess_1/stdsn/h/serializable.hpp>
#include <oess_1/stdsn/h/errno.hpp>

См. исходные тексты.

Пространства имен

namespace  oess_1
namespace  oess_1::stdsn

Классы

class  refcountable_policy_t
 Политика владения указателем на основе подсчета ссылок. Подробнее...
class  cloneable_policy_t
 Класс политики умного указателя, основанной на клонировании объектов при копировании. Подробнее...
struct  shptr_type_tag
 Тег, который должен показывать, к какому типу нужно делать кастинг в классе умного указателя. Подробнее...
class  shptr_skeleton_t
 Каркас для реализации функциональности умных указателей. Подробнее...
class  shptr_t
 Класс умного указателя на сериализуемый объект. Подробнее...

Макросы

#define _OESS_1__STDSN__SHPTR_HPP_
#define OESS_1_SHPTR_IFACE(shptr_type, referred_type, base_type)
 Макрос для упрощения настройки умных указателей.


Макросы

#define OESS_1_SHPTR_IFACE ( shptr_type,
referred_type,
base_type   ) 

Макроопределение:

private : \
  typedef base_type base_type_typedef__; \
  typedef base_type base_type_t; \
public : \
  shptr_type() {} \
  shptr_type( referred_type * p ) : base_type_typedef__( p ) {} \
  shptr_type( const shptr_type & o ) : base_type_typedef__( o ) {} \
  virtual ~shptr_type() {} \
  shptr_type & \
  operator=( const shptr_type & o ) \
  { base_type_typedef__::operator=( o ); return *this; } \
  referred_type * \
  get() { return cast_to( oess_1::stdsn::shptr_type_tag< referred_type >() ); } \
  const referred_type * \
  get() const { return cast_to( oess_1::stdsn::shptr_type_tag< referred_type >() ); } \
  referred_type * \
  operator->() { return get(); } \
  const referred_type * \
  operator->() const { return get(); } \
  referred_type & \
  operator*() { return *get(); } \
  const referred_type & \
  operator*() const { return *get(); } \
private :
Макрос для упрощения настройки умных указателей.

Класс oess_1::stdsn::shptr_t не предоставляет операторов разыменования указателей. Поэтому, его использование не так удобно, как, например, класса std::auto_ptr. Предполагается, что если требуется класс, аналогичный std::auto_ptr для конкретного сериализуемого класса, то такой класс будет реализован программистом. И в этом классе программист сам реализует все необходимые ему средства:

// Какой-то сериализуемый класс.
class some_class_t : public oess_1::stdsn::serializable_t
{
  ...
};
// Умный указатель, настроенный для some_class_t.
class some_class_ptr_t : public oess_1::stdsn::shptr_t
{
  OESS_SERIALIZER( some_class_ptr_t )
  public :
    some_class_ptr_t();
    some_class_ptr_t(
      some_class_t * p );
    some_class_ptr_t(
      const some_class_ptr_t & o );
    virtual ~some_class_ptr_t();

    some_class_ptr_t &
    operator=( const some_class_ptr_t & o );

    some_class_t *
    get();
    const some_class_t *
    get() const;

    some_class_t *
    operator->() { return get(); }
    const some_class_t *
    operator->() const { return get(); }

    some_class_t &
    operator*() { return *get(); }
    const some_class_t &
    operator*() const { return *get(); }
};

В большинстве случаев содержимое всех конкретных классов умных указателей будет одинаковым. Поэтому, для облегчения написания подобных классов предназначен макрос OESS_1_SHPTR_IFACE. С его помощью описанный выше some_class_ptr_t можно было написать так:

// Какой-то сериализуемый класс.
class some_class_t : public oess_1::stdsn::serializable_t
{
  ...
};
// Умный указатель, настроенный для some_class_t.
class some_class_ptr_t : public oess_1::stdsn::shptr_t
{
  OESS_SERIALIZER( some_class_ptr_t )
  OESS_1_SHPTR_IFACE( some_class_ptr_t, some_class_t,
    oess_1::stdsn::shptr_t )
};

Внимание:
Конкретные классы умных указателей необходимо описывать в DDL. Например, класс some_class_ptr_t нужно описать:
{type	some_class_ptr_t
	{super oess_1::stdsn::shptr_t}
}
Макрос OESS_1_SHPTR_IFACE описывает только методы класса, а не весь класс целиком для:

Аргументы:
shptr_type Имя типа, в котором использован макрос (т.е. имя типа умного указателя). Это имя необходимо для описания конструкторов и деструктора. Поэтому это должно быть короткое (не полностью квалифицированное) имя -- например some_class_ptr_t, а не my_namespace::some_class_ptr_t.
referred_type Имя типа, на который указывает умный указатель. Должен быть полностью квалифицированным именем типа (т.к. это имя передается в метод oess_1::stdsn::shptr_t::cast_to(), то оно должно быть точно таким, каким указано в DDL).
base_type Имя типа, от которого произведен данный класс умного указателя. Может быть полностью квалифицированным именем типа.
Параметр base_type введен в OESS_1_SHPTR_IFACE для того, чтобы можно было создавать классы умных указателей для иерархии наследования. При этом сами классы умных указателей образовывали бы свою иерархию. Например:

// Базовый тип...
class my_base_t : public oess_1::stdsn::serializable_t
{
  ...
};
// ... и умный указатель для него.
class my_base_ptr_t : public oess_1::stdsn::shptr_t
{
  OESS_SERIALIZER( my_base_ptr_t )
  OESS_1_SHPTR_IFACE( my_base_ptr_t, my_base_t,
    oess_1::stdsn::shptr_t )
};
// Производный класс...
class my_derived_t : public my_base_t
{
  ...
};
// ... и умный указатель для него.
class my_derived_ptr_t : public my_base_ptr_t
{
  OESS_SERIALIZER( my_derived_ptr_t )
  OESS_1_SHPTR_IFACE( my_derived_ptr_t, my_derived_t,
    my_base_ptr_t )
};

Благодоря этому ссылку на объект my_derived_ptr_t можно передать как ссылку на объект my_base_ptr_t:

void
f( const my_base_ptr_t & ref )
{
  ...
}

void
g()
{
  my_derived_ptr_t ptr( new my_derived_t() );
  f( ptr );
}

Макрос OESS_1_SHPTR_IFACE(shptr_type, referred_type, base_type) раскрывается следующим образом:

private :
  typedef base_type base_type_t;

public :
  // Конструкторы и деструктор.
  shptr_type() {}
  shptr_type( referred_type * p ) : base_type_t( p ) {}
  shptr_type( const shptr_type & o ) : base_type_t( o ) {}
  virtual ~shptr_type() {}

  // Оператор копирования.
  shptr_type &
  operator=( const shptr_type & o )
  { base_type_t::operator=( o ); return *this; }

  // Функции получения указателя, приведенного к нужному типу.
  referred_type *
  get() { return cast_to( shptr_type_tag< referred_type >() ); }
  const referred_type *
  get() const { return cast_to( shptr_type_tag< referred_type > ); }

  referred_type *
  operator->() { return get(); }
  const referred_type *
  operator->() const { return get(); }

  referred_type &
  operator*() { return *get(); }
  const referred_type &
  operator*() const { return *get(); }

private :
Примеры:
sample/subextension.auto_ptr/main.cpp и sample/subextension/main.cpp.


Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:36 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz