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 10635 articles. 8 followers. Post

2 Replies
206 Views

Similar Articles

[PageSpeed] 47


  • 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...

Casting a file pointer to char pointer
Hello everybody, I am reading a file into a char array. Because of which we cannot give array size in GBs of data. Is there a technique through which i can cast a file pointer to char pointer directly, so that in the "main" function, when i'm calling the function, i can directly pass converted file pointer as an argument. Please let me know asap. Thanks & Regards, Abhishek PM Abhishek opined: > Hello everybody, > > I am reading a file into a char array. Because of which we cannot > give array size in GBs of data. Is there a technique through which i > can...

Cast of pointer to base to pointer to derived
Consider the following code: class A { public: void SpecialFun() {} }; class B { public: static B* Create() { return new B(); } private: B() {} protected: A iA; }; class C : public B { public: void InvokeSpecialFun() { iA.SpecialFun(); } }; int main(void) { B* b = B::Create(); /* <Legal?> */ ((C*)b)->InvokeSpecialFun(); /* </Legal?> */ delete b; return 0; } In other words i need to invoke some function from the protected member of class B. So I derive from it into class C. Unfortunately, the constructor of B is private, I can only create the object using facto...

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). >...

Casting from pointer types to non-pointer types
I am interfacing with a third party API (written in C, if that matters) that has an "event handler" function with the following definition: void event_handler(int event_code, unsigned long user_data); The function takes an event code along with the user data but does not act on or change the user data. In my application, I want to pass a pointer as the user data. This pointer is to an array allocated with new, say, as follows: char *array = new char[100]; and passed to the event handler as follows: event_handler(1, reinterpret_cast<unsigned long>(array)); My question is ...

Do not cast pointers to functions to pointers to primitive types
Not sure if this is the right place or OT. One of the Parasoft coding guidelines (which I am using for current project) is "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]" EXAMPLE(from parasoft document): void Foo(char *ptrC) { *ptrC = 0; return; } void f() { void *ptrV = 0; void (*funPtr) (char*) = 0; funPtr = &Foo; ptrV = (void*)funPtr; // Violation of the rule and raise error return; } I can see why it is a bad idea not to write code this way. But can any one explain where this kind of co...

Cast a pointer to array to base class pointer to array
Hi, A have a pointer to an array of a derived class, which I want to cast to its base class. That is, im trying to do something like this: void f( derivedClass* derivedData[] ) { baseClass* data[] = dynamic_cast<baseClass*[]>(derivedData); } This can't compile, so I'm wondering how to make it work? Best Regards Hansen Hansen wrote: > Hi, > > A have a pointer to an array of a derived class, which I want to cast to > its base class. That is, im trying to do something like this: > void f( derivedClass* derivedData[] ) > { >...

Smart pointer
I was wondering about the possibility to havesmart pointers in the next FORTRAN standard. As far as I know they will be present in the next C++. More then the pointers, I think, that the allocatables may be extended in order to have more than one allocation. Of course I don't know how big this effort may be and all the subtleties involved. I'm thinking at a syntax like: type(xxx), nultiallocatable :: a, b allocate(a) ! Allocated call add_alloc(a, b) ! now a and b are alias deallocate(a) ...

Casting function pointer to different signature
/* Hello, To implement a C++ simulation I was working on, I started looking at Vladimir Batov's code from CUJ, Feb 2001 ("Callbacks Made Easy with the Observer-Mediator Design Patterns"). Most of the code is straightforward, but I can't follow the central mechanism behind his design that lets it work. I've boiled the problem down to the code below -- specifically the function doSomethingVoidPtr, where casting a function pointer's signature to a different signature lets the code bypass the compiler's type checking of function arguments. The console output follo...

pointers casting up|down
i can't seem to get inheritance|polymorphism to work. i create a vector of base* like so: vector<base*> stuff; for ( int i = 0; i < 4; ++i ) { derived* foo = new derived(...args...); stuff.push_back(foo); } but when i then call stuff[n].overridden_function() it calls base::overridden_function() and not derived::overridden_function()! what am i missing? [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] jsnX wrote: > i can't seem to get inheritance|polymorphism to work. i create ...

Smart Pointers
Hello, I am having a doubt about smart pointer. I wrote a smart ptr class with limited functionalities. I want to do like this! CSmartPtr <CSomeClass> test = new CSomeClass; // here i need to call a function which will start a thread and returns once it starts the thread. Here i should able to increment the refcount of smart pointer and should decrement once the thread finishes executing. What i should do here? Can anybody please advice me? The code will looks like this. while (bDone) // loop forever { // do some process here. if (acce...

casts and pointers
[repost] [snipped from elsewhere] >>I can't see how to cast an integer to a pointer. > You can't. Fortran doesn't do that - not even with the C interop stuff. > Of course,you can always play around with TRANSFER, but recall that the > standard says that the resulting values are undefined when you type > cheat with TRANSFER. And you can do it in C. You can't do it portably in C, either. I believe you can memcpy() in to an (unsigned char *) and back again. If sizeof(int) >= sizeof(void*) you might be able to do the cast, but the use of the value of the ...

Smart pointers and this
I'm using reference counted smart pointers in a small project and it's a breeze, but I'm running into a problem which I don't know how to approach. Consider something like this: class A { public: A() {} void setObserver(counted_ptr<B> observer) { _observer = observer; } private: counted_ptr<B> _observer; }; class B { public: B() { _a = counted_ptr<A>(new A); _a->setObserver(counted_ptr<B>(this)); } private: counted_ptr<A> _a; }; >From what I can see, the problem is creating a smart pointer with an...

casting pointers
Hi, I've this question: suppose we have two differently typed pointers: struct foo *foo; char **array; Becase one can always legally cast any pointer to (void *), and becase (void *) is assignable to any pointer type, is it ever necessary to cast when assigning one pointer type to another? I.e. since foo = (void *) array; is legal (or is it?), isn't the (void *) there just line noise? TIA On Sat, 4 Oct 2003 16:36:48 UTC, rihad <rihad@mail.ru> wrote: > Hi, I've this question: suppose we have two differently typed pointers: > > struct foo *foo; > char **arr...

pointer cast
Hi everyboy, somebody could tell me what meen the following cast: a = (struct foo 8) b c = int (func) (int) Thanks Carlos Carlos F. <prohto@yahoo.com> spoke thus: > a = (struct foo 8) b If you meant (struct foo *) b, it's pretty self explanatory - cast b to a foo pointer and assign it to a. Whether it results in well-defined behavior or not depends on what a and b are declared as and what's happened prior to the line in question. > c = int (func) (int) Depends on what func is, and it's probably illegal anyway unless func is an obfuscated macro. Post more code....

About casts (and pointers)
Some time a go, in a discussion here in comp.lang.c, I learnt that it's better not to use a (sometype **) where a (void **) is expected (using a cast). Part of the discussion boiled down to the rule: if I cast a (sometype **) to a (void **) I am making a number of assumptions about the implementation's (void **) representation and length. Specifically, if I do the above cast I'm assuming that a (sometype **) and a (void **) have the same size and representation, and this might not always be true. Ok, all clear up to this point. But now my question is: does the above rule generaliz...

casting between pointers
hi, why does the following produce an output of 64769 instead of 1 int main() { bool* pBool = new bool(false); unsigned short* pUS = (unsigned short*)pBool; cout << *pUS; delete pBool; return 0; } I expected the output to be 1 since the size of a bool and the size of an unsigned int is 1 scroopy <scroopy@nospam.com> wrote: > why does the following produce an output of 64769 instead of 1 Because you get undefined behaviour when casting one pointer type to another and using it as that. You know .. the demons-fly-out-of-your-nose issues .. > int main() >...