Casting smart pointer?

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
Andrew
3/25/2009 12:34:16 PM
comp.lang.c++.moderated 10706 articles. 11 followers. allnor (8507) is leader. Post Follow

2 Replies
311 Views

Similar Articles

[PageSpeed] 7
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
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
Arne
3/25/2009 7:47:23 PM
Reply:
Similar Artilces:

How to "cast" in Ruby
Hi, I need to know how to "cast" ruby objects on another i.e. arr = Array.new() doc = REXML::Document.new(grListXML) doc.elements.each("*/group") do |el| temp = el.elements["id"].get_text arr << temp end I want to convert temp variable to intager. Is is any simple way to do it if REXML has no to_i methods? Thanks for any help. MT -- Posted via http://www.ruby-forum.com/. Hi -- On Tue, 21 Aug 2007, Marcin Tyman wrote: > Hi, > I need to know how to "cast" ruby objects on another i.e. > > arr = Array.new() > doc = REXM...

Pointers In C++
A pointer is a variable which stores the address of another variable. There are two important operators when working with pointers in C++: the address of (&) operator and the value of (*) operator. They have been overloaded in C++ so they may have different uses in different contexts. How much storage space does a pointer consume? Use sizeof(ptr) without the '*' operator to determine the memory utilised on your system. Irrespective of datatype or whether the pointer points to a single variable or array, as a general rule, pointers must use the same amount of memory space. The &...

Up casting and down casting
How is up casting and down casting performed? Maybe it's an implementation detail, but hopefully it's something that most compilers implement in the same way. My first guess was that the compiler places the base class at the beginning of the derived class, so that both have the same address. But that wouldn't work in the case of multiple inheritance. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Sosuke wrote: > How is up casting and down casting performed? Maybe it's an > implementation detail, but hopefully it's something that most > compilers impl...

Pointer Qs
I used to do lots and lots of C coding back in the pre-ANSI days. I just picked up a project that has lots of pointers running around. Now I'm seeing things like char utf8char[6]; .... xxx = letter((char *)&utf8char); where void letter( char *somechar) { .... } Back in the "old" days we would have simply said: char utf8char[6]; .... xxx = letter(utf8char); so what's the purpose of the (char *)& shenanigans? I mean, it works, so it must be right, but I always thought that using an array name without the subscript returns a pointer to the first element anyway......

Questions on pointer type for merging of linked list problem in Elements of programming interviews.
Elements of Programming Interviews gives the following code for merging lin= ked lists. My questions are: Is it ok for merge_sorted_linked_lists to use= call by reference instead of call by value? Also, are std::unique_ptr or = raw pointers ok besides the author's use of shared pointers? Would unique = pointers be preferable? Can we use unique pointers by simply using std::move for every assignment? = For example, if we use unique pointers, do we replace tail->next =3D n; by= tail->next =3D std::move(n); Does that approach work straightforwardly or= are there complica...

Smart features and controlling the driving sketch ...
Someone just pointed out something to me on these smart features of smart p= arts. So far I have only used smart features for panel mounted components = so they will automatically cut same mounting holes. Now one of my engineer= s decided not to move the component in the assembly and updating the smart = feature. He just went to the part file and edited the sketch. This allowe= d him to edit the smart features sketch outside of the smart feature contro= ls. And you can guess what happened, the panel component did not fit into = the newly defined hole. =20 So what we have is when y...

Cast to void???
In Loki (smartptr.h), I've noticed the following expression occurring by itself: (void)val; What is the purpose in casting something to void, especially in a stand-alone expression such as this and not as part of something larger? I'm surprised this is possible as it is not possible to declare a variable of type void. And I'm intrigued to learn the purpose... Here's the context I see this in: static void OnDereference(P val) { assert(val); (void)val; } BTW, I see this in the VC++ port of Loki. I don't know if it's in the original Loki or not... Thanks, Dave D...

Why casting necessary?
Why is so necessary sometimes in C++ that you have to cast a pointer between a base object and a derived object? Could you give me some examples for me to understand this concept deeply? Thanks for your help! "alg" <alg36897@yahoo.com> wrote: > Why is so necessary sometimes in C++ that you have to cast a pointer between > a base object and a derived object? Could you give me some examples for me > to understand this concept deeply? > > Thanks for your help! Here is an example. <http://www.objectmentor.com/resources/articles/visitor> The article a...

Arrays of pointers
Hello. I am rather new at FORTRAN, and I have a problem with the type system (F90). I have a binary tree type: TYPE tree TYPE (tree), POINTER :: left, right .... END TYPE tree and I usually do: TYPE (tree), POINTER :: my_tree my_tree => build_tree(...) where new_tree allocates space for it and constructs the tree. Now I need several trees in a dynamically allocated array, but I cannot make an array of pointers. I could probably refactor my code so that build_tree works on an already allocated object, so that it does not require a pointer, but is there some way I could really have an (a...

smart pointers #2
Is there a difference between smart pointers and automatic pointers or they refer to the same idea. -Thanks * Mohammad: > > Is there a difference between smart pointers and automatic pointers or > they refer to the same idea. Can you give an example of what you mean by 'automatic pointer'? -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? Alf P. Steinbach wrote: > * Mohammad: > >>Is there a difference between smart pointers and au...

What does this cast do?
Hi all, allow the code to explain: *((volatile unsigned char *) 0xe00e0f3c) = 0x00800000; If curious, this code is in local_bus_init() , in the u-boot bootloader for linux for a ppc proccessor. Robert robert wrote: > Hi all, allow the code to explain: > > *((volatile unsigned char *) 0xe00e0f3c) = 0x00800000; > > If curious, this code is in local_bus_init() , in the u-boot > bootloader for linux for a ppc proccessor. This is a non-Standard piece of code using implementation-defined cast magic to convert an integer (fx:OT which /probably/ expresses an address in som...

to cast or not to cast malloc ?
The answer is neither. Use macros. #define ALLOC(size, type) ((type) *) malloc((size) * sizeof(type)) #define NEW(type, name, size) (type) * (name) = ALLOC((size), (type)) They are both [more] type-safe and concise. Compare: NEW(int, x, 1000); to int * x = (int*) malloc(sizeof(int) * 1000); I'm sure someone must have "discovered" this before. Anyways HTH. MSG MSG wrote: > The answer is neither. Use macros. > > #define ALLOC(size, type) ((type) *) malloc((size) * sizeof(type)) > #define NEW(type, name, size) (type) * (name) = ALLOC((size), (type)) > >...

How Merkans were once smart..
and are now turning poopie heads: http://www.larouchepub.com/other/2004/3132leibniz_pfv.html Newton was an asshole! In article <259280e4.0408171652.1e9e984f@posting.google.com>, berlutte@hotmail.com (Voyageur) wrote: > and are now turning poopie heads: > > http://www.larouchepub.com/other/2004/3132leibniz_pfv.html > > > Newton was an asshole! The probability you understand anything of substance in Newton's or Leibniz's work is exactly zero. In article <waderameyxiii-2AF22C.21241118082004@news.supernews.com>, The World Wide Wa...

Function Pointer ! How and Why ? #2
In C, I have a doubt about Function pointers. Lets say , typedef void (*test_audit_proc_t)( int *t, int index, int instnb); typedef struct a_index { test_audit_proc_t test_mo_proc; } test_audit_proc_index_t; test_audit_proc_index_t t1[100]; Then After filling t1[i].test_mo_proc = fn; ... in another function lets say Sample 1: void xyz() { test_audit_proc_t *proc; *proc = t1[2].test_mo_proc ; -> Gives Sig 11 here (*proc)(.......); } But if i give Sample2 : void xyz() { test_audit_proc_t proc; proc = t1[2].test_mo_proc ; -> Gives Sig 11 here ...

what is NULL pointer dereferencing
I am not getting the exact idea. Can you please explain me with an example. Thanks "prashant.khade1623@gmail.com" wrote: > > I am not getting the exact idea. > > Can you please explain me with an example. Please state your question in the body of your article - thanks. A NULL pointer is not /for/ dereferencing. Setting a pointer to NULL indicates that the pointer does not point to a usable value and should not be dereferenced. -- Morris Dovey DeSoto Solar DeSoto, Iowa USA http://www.iedu.com/DeSoto/ Morris Dovey wrote: > "prashant.khade1623@gmail.com&quo...

smart bad sector marking tool
Hi. My disk has some bad sectors which are stable during last half year. Most of them are marked as bad (FAT32) Under Win2000 I have permanent bad sector problems. I need to scan my disk and mark all bad sectors and mark in addition few preceding and following good sectors wchich may become bad in the future. Due to quite big number of bad sectors it can't be done manually. (I tried, but it costs a lot of time and patience: check where is bad sector and then find proper mapping place inside FAT structure and then mark.) My problem is: during normal scandisk work some bad se...

Ooh, it smarts
Had my eye surgery today, so they're now aligned properly. Had pretty much the same day as Scrib had. -- ..sig for rent Apply within On Mon, 31 Oct 2005 20:35:26 +0000, Lister <misterlister169@gmail.com> wrote: >Had my eye surgery today, so they're now aligned properly. Had pretty >much the same day as Scrib had. Did you have sight in your wonky eye? Or is it more of a blind in that eye and it's just being corrected for asthetics? -- **************The Starglider*************** Public E-Mail. * http://www.starglider.dynu.com/radio * Ask fo...

The Java no pointer big fat lie!
Whenever I read a Java book and it states that Java has no pointers, it makes my teeth grind. It would be more accurate to say Java only uses pointers. That's right. Java only uses pointers. However, that also wouldn't be entirely accurate either, but it would be closer to the truth then to say Java doesn't use pointers. When these books make these claims they're usually explicitly or implicitly comparing the Java memory addressing method to the C/C++ memory addressing methods. C++ has three main methods for addressing memory. (concrete, pointer, and reference) Concrete ad...

malloc
I've always casted the result of a call to c/malloc viz.: int * ptr = (int *) calloc(10, sizeof(int)); However, I know this is not strictly necessary as there is always an implied cast on the void pointer that is returned. A potential reason for not casting was pointed out to me today by Martin Dickopp (cheers Martin). I just wondered what the thoughts of the group were on this. Cheers, -- EvilRix On Fri, 13 Feb 2004 06:55:24 -0000, "EvilRix" <evilrix@[@@@]hotmail.com> wrote: >I've always casted the result of a call to c/malloc viz.: > >int * ptr = (i...

Orange Cast or Better Color in Epson 3200 Scan Vs Vuescan
Arrrg. I've tried using Vuescan's color profile for Afga 160 (neg) comparing it against Epson's "Generic" color neg setting. Vuescan is consistently "cooler" (lacking red I think). Blah. (I have this problem with Kodak too) The Epson scan's look better to my amateur eye. I've spent a lot of time (Advance Workflow, Generic Film Settings, Changing Color settings etc. etc) trying to tune and tweak Vuescan but I'm still not happy. I'm guessing I'm seeing a bit of an orange cast in the Epson scan, "warming" things up for me, try t...

cast
I have written this wrapper function that seems to compile into an object file just fine. #include "main.h" struct addrinfo ad, *adp; static int stat; struct addrinfo **ginfo(char *port) { memset(&ad, '\0', sizeof ad); ad.ai_family = AF_INET; ad.ai_socktype = SOCK_STREAM; ad.ai_flags = AI_PASSIVE; if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) { fprintf(stderr, "Error: %s\n", gai_strerror(stat)); exit(EXIT_FAILURE); } return (struct addrinfo **)stat; } Just above is the code in question...

Smart Cars 2.1
The game Smart Cars releases an all-absorbing line of arcade races. You drive a racing car and your objective is to be the first at the finish first. The game gives you a feeling of speed and danger. Every level of the game is full of obstacles, which you need to overcome in a limited period of time taking different routes. The obstacles reduce the speed, skid your car or cause a car crash. Your car will encounter different checks in your way. The speed of your car reduces if you take an earth road. You can pick up such bonuses as life, scores, speed, and a gun. Ready to go for it? Dow...

Common practice in casting design
I'm looking to gather information on what some of the casting designers in the group do when they approach a casting design problem. I've done a few aluminum castings this year, but I am beginning to fell like I may not be going about it in the most efficient manner. What I have been doing is to design the part in its machined state (all of my castings have had significant machining done as finishing operations). Designing in it machined state allows me to readil control the position of the machined interfaces realtive to other parts in the assembly. When I have finished the design ...

FM7.2 bugs/issues, pointers -- request for feedback
I added a section for FM7.2 in the List of FM Bugs/Issues [ http://www.microtype.com/FM_bugs.html ] and also updated the FAQ with items related to FM7.2+XML [ http://www.microtype.com/FrameMakerFAQ.html ] If you use the shipping version of FM7.2 and can report FM7.2-specific bug fixes or bugs/issues, your feedback is welcome and can benefit other users. One item that may be of interest to PDF producers: prior to FM 7.1, importing formats with document properties turned on reset the File Info values (File > File Info) as well, so that any file-specific information (such a...

cast function problems
Hi, In one of my tables, one of the columns (Salary) is of type varchar(255). I want to conver it into int(11). When I do a test to see if get the result, I have the following problems. select cast(Salary as unsigned int) from mydb; Truncated incorrect INTEGER value: '150000.00' ie, if the Salary has a decimal point, it gives me an error. Any suggestions? Thanks. Actually, I am trying to insert this salary value ( from varchar(255)) into a table which has a type int(11). Thats when I get this trouble. insert into mydb2 (select cast(Salary as unsigned int) from mydb) Truncate...