Grantig friend status to template

A

Ales DOLECEK

Hello,

I'm trying to created base class and template for "smart" pointer
pointing to it. It should do simple reference counting and clean up when
the reference count reaches zero. The header looks like this:

class base_t {
int _ref_count;
public:
base_t(void): _ref_count(0) {};
}

template <typename T>
class ptr_t {
T *_target;
public:
ptr_t(void): _target(NULL) {};
ptr_t(T *);
ptr_t(ptr_t &);
virtual ~ptr_t(void);
T *operator->(void) {return _target;};
T &operator*(void) {return *_target;};
const T &operator*(void) const {return *_target;};
ptr_t &operator=(ptr_t &);
operator bool(void) const {return bool(_target);};
};



My intention is to create descendant classes like:

class child_t: public base_t
{
// ... members here
public:
// ... more members here
};

typedef ptr_t<base_t> child_p;



I have following questions:

1) Because base_t::_ref_count is private I have to make ptr_t it's
friend - but it is template. How can I specify that all classes created
with ptr_t<T> are friends of base_t?

2) Is there way to specify that type T in ptr_t<T> must be direct (or
indirect) descendant of base_t type?

Thank you all in advance.
Ales
 
A

Ales DOLECEK

My intention is to create descendant classes like:

class child_t: public base_t
{
// ... members here
public:
// ... more members here
};

typedef ptr_t<base_t> child_p;

Should be

typedef ptr_t<child_t> child_p;

of course.
Ales
 
A

Ales DOLECEK

Hello,

I'm trying to created base class and template for "smart" pointer
pointing to it. It should do simple reference counting and clean up
when the reference count reaches zero. The header looks like this:

class base_t {
int _ref_count;
public:
base_t(void): _ref_count(0) {};
}

template <typename T>
class ptr_t {
T *_target;
public:
ptr_t(void): _target(NULL) {};
ptr_t(T *);
ptr_t(ptr_t &);
virtual ~ptr_t(void);
T *operator->(void) {return _target;};
T &operator*(void) {return *_target;};
const T &operator*(void) const {return *_target;};
ptr_t &operator=(ptr_t &);
operator bool(void) const {return bool(_target);};
};



My intention is to create descendant classes like:

class child_t: public base_t
{
// ... members here
public:
// ... more members here
};

typedef ptr_t<base_t> child_p;



I have following questions:

1) Because base_t::_ref_count is private I have to make ptr_t it's
friend - but it is template. How can I specify that all classes
created with ptr_t<T> are friends of base_t?

2) Is there way to specify that type T in ptr_t<T> must be direct (or
indirect) descendant of base_t type?

Thank you all in advance.
Ales

I could also declare the smart pointer as inner class of base_t

class base_t
{
int _ref_count;
protected:
class pointer
{
...
}
public:
base_t(viod);
}

but then I don't know how could I create descendants of base_t::pointer.

Ales
 
R

Rob Williscroft

Ales DOLECEK wrote in
Hello,

I'm trying to created base class and template for "smart" pointer
pointing to it. It should do simple reference counting and clean up
when the reference count reaches zero. The header looks like this:

1st a forward declaration:

template said:
class base_t {
int _ref_count;
public:
base_t(void): _ref_count(0) {};

template <typename T>
friend class ptr_t;

Are you're missing a virtual dtor here ?:

virtual ~base_t{} {}
}

template <typename T>
class ptr_t {
T *_target;
public:
ptr_t(void): _target(NULL) {};
ptr_t(T *);
ptr_t(ptr_t &);

Are you intending to derive from this class ?
virtual ~ptr_t(void);
T *operator->(void) {return _target;};
T &operator*(void) {return *_target;};
const T &operator*(void) const {return *_target;};
ptr_t &operator=(ptr_t &);
operator bool(void) const {return bool(_target);};
};



My intention is to create descendant classes like:

class child_t: public base_t
{
// ... members here
public:
// ... more members here
};

typedef ptr_t<base_t> child_p;



I have following questions:

1) Because base_t::_ref_count is private I have to make ptr_t it's
friend - but it is template. How can I specify that all classes
created with ptr_t<T> are friends of base_t?

2) Is there way to specify that type T in ptr_t<T> must be direct (or
indirect) descendant of base_t type?

in ptr_t<> add:

base_t *as_base() { return _target; }

then when you need to reference base_t::_ref_count do it as:

as_base()->_ref_count

If you do this at least once in the destructor ~ptr_t() then
ptr_t<T> won't compile unless T is convertible to base_t.

Alternatively:

If you have (or can get) boost (www.boost.org) then use:

::boost::is_base_and_derived<base_t, T>::value

in conjunction with static asserts:

http://www.boost.org/libs/static_assert/static_assert.htm

BOOST_STATIC_ASSERT( ::boost::is_base_and_derived<base_t, T>::value );


HTH

Rob.
 
G

GUMP

The declaration

template <typename T>
friend class ptr_t;

cann't get through the Microsft C++ compiler(I use VC 6.0),
can you tell me why?
thank in advance.
 
J

John Harrison

GUMP said:
The declaration

template <typename T>
friend class ptr_t;

cann't get through the Microsft C++ compiler(I use VC 6.0),
can you tell me why?
thank in advance.

Because VC++ 6's handling of templates is v. poor.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,217
Latest member
topweb3twitterchannels

Latest Threads

Top