Casting smart pointer?

  • Permalink
  • submit to reddit
  • Email
  • Follow


I have a smart pointer class called Handle...

template <class T>
class Handle
{
public:
	Handle();
	Handle(T*);
	Handle(const Handle<T>&);
	~Handle();

        ...
private:
	T* m_pTarget;
};

that always points to a class derived from another class called
Handleable.  (Handleable contains the reference count)

Now if I have a class B and class D as follows:

class B : public Handleable {...}
class D : public B {...}

and then I have a function

    void f(Handle<B>)

and call it as follows:

    Handle<D> d;
    f(d);

I would like the compiler to automatically cast my handle from a
Handle<D> to a Handle<B> (as B is a base class of D).

Is this possible?

I thought of something like this:

template <class T>
class Handle
{
     ...
     template <class S>
         operator Handle<S>() { return Handle<S>( m_pTarget ); }
     ...
}

But this will be ambiguous with the copy constructor, correct?  Is
there a way to avoid this?

Thanks,
Andrew.

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Andrew 3/25/2009 12:34:16 PM

See related articles to this posting

Andrew Tomazos schrieb:
> I have a smart pointer class called Handle...
> 
> template <class T>
> class Handle
[...]
> Now if I have a class B and class D as follows:
> 
> class B : public Handleable {...}
> class D : public B {...}
> 
> and then I have a function
> 
>     void f(Handle<B>)
> 
> and call it as follows:
> 
>     Handle<D> d;
>     f(d);
> 
> I would like the compiler to automatically cast my handle from a
> Handle<D> to a Handle<B> (as B is a base class of D).

The usual way is to provide a templated constructor similar to the copy
constructor:

template<class Y>
Handle(Handle<Y> const& other);

If you also provide a copy constructor, then it will be preferred,
because it is more specialised than the templated constructor.

See also the implementation of boost::intrusive_ptr
or my linked_ptr ( http://draig.de/linked_ptr/ ).

-- 
Thomas

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Thomas 3/25/2009 7:46:13 PM

Andrew Tomazos schrieb:
> I have a smart pointer class called Handle...
> 
> template <class T>
> class Handle
> {
> public:
> 	Handle();
> 	Handle(T*);
> 	Handle(const Handle<T>&);
> 	~Handle();
> 
>         ...
> private:
> 	T* m_pTarget;
> };
> 
> that always points to a class derived from another class called
> Handleable.  (Handleable contains the reference count)

So why don't you make it a simple class that stores a pointer to
Handleable?

> I would like the compiler to automatically cast my handle from a
> Handle<D> to a Handle<B> (as B is a base class of D).
> 
> Is this possible?

Yes, quite easily if you have an method to retrieve the internal
pointer (let's call it get()).

template<class T>
class Handle
{
   /*...*/
public:
   T* get() const
   { return m_pTarget; }

   template<class U>
   Handle(Handle<U> const& other) : m_pTarget(other.get()) //(1)
   { /* do the ref-counting */ }
};

(1) compiles if and only if U* is convertible to T*, that is if U is
derived from T, T is void or U is T. The case T==void should be
a-voided by some sort of static assertion that Handle<void> can't be
instantiated, and the case U==T cannot arise because the compiler
would prefer the copy construtor over the templated one.

> 
> I thought of something like this:
> 
> template <class T>
> class Handle
> {
>      ...
>      template <class S>
>          operator Handle<S>() { return Handle<S>( m_pTarget ); }
>      ...
> }
> 
> But this will be ambiguous with the copy constructor, correct?  Is
> there a way to avoid this?

Prefer conversion by some constructor of the target type over
conversion by some conversion operator.

There are several libraries that provide means to detect at compile
time whether one type is derived from another, e.g. the loki library
and I am pretty sure you'll find something useful in the boost
libraries as well.

greets
Arne

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Arne 3/25/2009 7:47:23 PM
comp.lang.c++.moderated 10589 articles. 6 followers. Post

2 Replies
190 Views

Similar Articles

[PageSpeed] 6

  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

casting my smart pointer up and down
Hi there, I am writing a smart pointer that is similar to the boost intrusive ptr. I am trying to make it behave like a c++ pointer including the implicit and explicit casting behaviour. Below is the part more or less relevant to my problem. Version 1 is fine for casting to a derived class, but it must be called explicitly even though it is used to cast to a base class. Version 2 is fine for implicitly casting to a base class, but will never cast to a derived class Version 3 is really bad. It will cast to a derived class implicitly, which is not what I want. I cannot use 1 and 2 the s...

Casting smart pointers
Hi everybody: I have implemented a Pointer class template that uses reference counting to deallocate memory automatically. I have the following code using my Pointer: char* auxchar = new char[100]; strcpy(auxchar, "Hola mundo"); Pointer<char> charPointer = Pointer<char>(auxchar); .... Is possible to implement an operator overloading or some stuff to do something like this: printf("Message: %s\n", charPointer); that should return a <T*> to avoid create a method like charPointer.getData() ? Thanks in advance Ernesto In article <f7c444ea.040...

canonical up-cast idiom for smart pointers?
I'm wondering if there is a way to do this properly. I feel like I am missing something. I have two distinct classes. They don't have much at all in common. I want a vector-like container that contains smart pointers (boost::shared_ptr or similar) to a set of these two classes and keeps them sorted wrt each other. For example if I insert ClassA, ClassA, ClassB, ClassA, ClassB in that order, I want to re-visit them in that same order when I iterate later. My first thought was to make an artificial base class that has a 'type' argument indicating which "derived" ty...

Smart Pointers: Is there something similar to smart pointers in C?
Hi Experts, I've just joined this group and want to know something: Is there something similar to smart pointers in C or something to prevent memory leakages in C programs. Regards MotoK MotoK a �crit : > Hi Experts, > I've just joined this group and want to know something: > Is there something similar to smart pointers in C or something to > prevent memory leakages in C programs. > > Regards > MotoK > There is something much better: a garbage collector. Using a garbage collector obviates the need for smart pointers, constructors, destructors, weird lang...

casts of pointers to pointers
Hello, am I correct that in general a cast from "a pointer to a pointer to A" to "a pointer to a pointer to B" is only defined behavior if A and B are compatible? In particular, does this mean that in int x, *p = &x, **q = &p; (const int**)q; the last line may lead to undefined behavior? In the standard I found the following: [6.3.2.3] A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. [6.2.5p28] Po...

smart pointer smart constness ...
Hello, I recently got bitten by the difference between a const pointer and a pointer to const, in the following unpleasant way: ---- start simplified example ---- #include <iostream> #include <ostream> #include <memory> using namespace std; class A { private: int a; public: A(int i): a(i) { }; void transform() { ++a; } void print() const { cout << "A with value " << a << endl; } }; class B { private: auto_ptr<A> a; B(const B&); B& operator=(const B&); public: B(): a(new A(0)) { } void transform() { ...

Once again pointer to first element vs pointer to array cast to pointer to element
I know that this topic has been discussed a lot, still I'd appreciate a clear cut (and correct) answer: I pass a multidimensional array to a function, which is defined as int f(int a[10][10]) { int *b=(void*)a; int *c=a[0]; /*...*/ } Now the questions come: - Is it guaranteed that b and c points to the same object (or is this implementation defined)? - Is it always true that a[1][1] refers to the same object as c[11] ? (There is no hole) - Does dereferencing b violate any aliasing rule? Thanks Szabolcs Szabolcs Borsanyi wrote: > I know that this topic has been discussed a lot, s...

Smart pointers and member function pointers
Does anybody know of a smart pointer that supports 'operator->*'. As yet I've always had to use this type of expression ((*sp).*pFnc)() where sp .... Smart pointer to Obj pFnc .. Member function pointer ( void (Obj::*TYPE)(void) ) but never with (sp->*pFnc)() which is possible for pointers. n2xssvv g02gfr12930 wrote: > Does anybody know of a smart pointer that supports 'operator->*'. > > As yet I've always had to use this type of expression ((*sp).*pFnc)() > where > > sp .... Smart pointer to Obj > pFnc .. Member function po...

Casting from lib.pointer to a double pointer
Hi guys, I want to do the following thing from Matlab: I have a variable v of type lib.pointer (default this is a pointer to void). I want to convert/cast this variable to a var d of type double (or pointer to double). Could you help me with this? Thanks, Lucian On Sun, 15 Mar 2009 16:03:02 -0400, A A <lucirev@yahoo.com> wrote: > Hi guys, > > I want to do the following thing from Matlab: > I have a variable v of type lib.pointer (default this is a pointer to > void). I want to convert/cast this variable to a var d of type double > (or pointer to double). >...