473,837 Members | 1,701 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 same time, or is there a workaround that makes
the compiler think of them as different members?

template<typena me T>
class THE_API Ref
{
public:
Ref( void ) : _pObj( NULL ) { }
Ref( T* Source ) {_set( Source ); }
Ref( const Ref<T>& Source ) {_set( Source._pObj ); }

// Version 1. would cast only explicitly
template< typename CASTTYPE > explicit
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}

// Version 2. is implicit and performs an implicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( Source.GetNativ ePtr( ) );
}

// Version 3. is implicit but performs an explicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}

template< typename CASTTYPE >
explicit
Ref( CASTTYPE* source )
{ // error C2440: Did you cast T* to Ref<Ref<T> > ?
_set( static_cast<T*> ( source ) );
}

private:
void _dec( ) { if( _pObj ) if ( !(--(_pObj->_refCount) ) )
delete _pObj; }
void _inc( ) { if( _pObj ) ++(_pObj->_refCount); }
void _set( T* Ptr ) { _pObj = Ptr; _inc( ); }
};
Jul 22 '05 #1
5 3154
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote in message
news:cp******** **@svr7.m-online.net...
// Version 1. would cast only explicitly
template< typename CASTTYPE > explicit
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}

// Version 2. is implicit and performs an implicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( Source.GetNativ ePtr( ) );
}

// Version 3. is implicit but performs an explicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}


I like version 2 because it seems the safest, and allows for the usual
construct

Ref<Base> f() {
Ref<Derived> out(new Derived);
...
return out;
}

As for static_cast or dynamic_cast from the base to the derived class, with
ordinary pointers one writes

Derived * d = static_cast<Der ived *>(b);

But static_cast and dynamic_cast cannot be overloaded. So you could add new
member functions. Eg.

template <class T>
class Ref {
public:
template <class U>
Ref<U> do_dynamic_cast () const {
return Ref<U>(dynamic_ cast<U*>(GetNat ivePtr()));
}
};

Ref<Base> b = f();
Ref<Derived> d = b.template do_dynamic_cast <Derived>(b);
There might be better soultions with operator conversions, etc.
Jul 22 '05 #2
Siemel Naran wrote:
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote in message
news:cp******** **@svr7.m-online.net...

// Version 1. would cast only explicitly
template< typename CASTTYPE > explicit
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}

// Version 2. is implicit and performs an implicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( Source.GetNativ ePtr( ) );
}

// Version 3. is implicit but performs an explicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*> ( Source.GetNativ ePtr( ) ) );
}

I like version 2 because it seems the safest, and allows for the usual
construct


it is as safe as 1. but both have a lack of capability.
1. is not able to cast to base implicitly ( but c++ pointer can do )
2. is not able to cast to derived class explicitly
( but c++ pointer can do )
And my golden goal is to achieve behaviour as close as possible to c++
pointer
Ref<Base> f() {
Ref<Derived> out(new Derived);
...
return out;
}
yes it does. This and any other cast to base is possible.
As for static_cast or dynamic_cast from the base to the derived class, with
ordinary pointers one writes

Derived * d = static_cast<Der ived *>(b);
yes, thats what I want with it
Ref<Derived> d = static_cast<Ref <Derived> >( b );

I use my own RTTI and I can ask any object for its runtime type and
verify any IS A relation. I could even make the cast checked, and throw
an appropriate exception.

But static_cast and dynamic_cast cannot be overloaded. So you could add new
member functions. Eg.

template <class T>
class Ref {
public:
template <class U>
Ref<U> do_dynamic_cast () const {
return Ref<U>(dynamic_ cast<U*>(GetNat ivePtr()));
}
};

Ref<Base> b = f();
Ref<Derived> d = b.template do_dynamic_cast <Derived>(b);
What is b.template? Sure you meant it like this?

Even though what you wrote is close to my goal. I already used folloing:

Ref< Base > b = d.as< Base >( );

This is using a template member function on the Ref-class.
It could also be used like a non-member template function.

Ref< Base > b = ref_cast< Base >( d );

Thats probably what you meant.
I must say that you led me back to a point where I have been, but forgot
in the meanwhile. If I make above method consistent all over the
project, I won't need to use the static_cast and it even writes shorter
and is nearly as descriptive as the static_cast.


There might be better soultions with operator conversions, etc.

So, if someone knows a way to get the last little step to make it really
like c++ pointers, go go go...

Ingo
Jul 22 '05 #3
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote in message
news:cpkrpg$9k7
Ref<Base> b = f();
Ref<Derived> d = b.template do_dynamic_cast <Derived>(b);
What is b.template? Sure you meant it like this?


It's required by the standard. It tells the compiler to parser to interpret
the < as the beginning of a template declaration rather than the less than
operator.
Ref< Base > b = ref_cast< Base >( d );

Thats probably what you meant.
Yes, that's good. By not using member functions, you don't have to use the
ugly .template syntax.
I must say that you led me back to a point where I have been, but forgot
in the meanwhile. If I make above method consistent all over the
project, I won't need to use the static_cast and it even writes shorter
and is nearly as descriptive as the static_cast.


There might be better soultions with operator conversions, etc.

So, if someone knows a way to get the last little step to make it really
like c++ pointers, go go go...

Ingo

Jul 22 '05 #4
Siemel Naran wrote:
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote in message
news:cpkrpg$9k7

Ref<Base> b = f();
Ref<Derive d> d = b.template do_dynamic_cast <Derived>(b);

What is b.template? Sure you meant it like this?

It's required by the standard. It tells the compiler to parser to interpret
the < as the beginning of a template declaration rather than the less than
operator.


I have never seen such syntax before and I cannot imagine *what* it is.
Can you post the declaration of that function?
Especially wether it is a member function or not. Because you write "b"
two times in that line.

Ref< Base > b = ref_cast< Base >( d );

Thats probably what you meant.

Yes, that's good. By not using member functions, you don't have to use the
ugly .template syntax.


Does that mean your version was a member function? Why do you pass it
the b as an argument?

Also my other version that writes like:
Ref< Derived > d = b.as< Derived >( );

is quite direct, and works well without "b.template ".
Jul 22 '05 #5
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote in message
Siemel Naran wrote:
Ref<Base> b = f();
Ref<Derive d> d = b.template do_dynamic_cast <Derived>(b);
BTW, I have one too many b's. Should have been
Ref<Derive d> d = b.template do_dynamic_cast <Derived>();
I have never seen such syntax before and I cannot imagine *what* it is.
Can you post the declaration of that function?
template <class T> Ref {
public:
template <class U>
Ref<U> do_dynamic_cast () const;
};
Especially wether it is a member function or not. Because you write "b"
two times in that line.


Mistake on my part. There should be just one b.

Ref< Base > b = ref_cast< Base >( d );

Thats probably what you meant.

Yes, that's good. By not using member functions, you don't have to use the ugly .template syntax.


Does that mean your version was a member function? Why do you pass it
the b as an argument?

Also my other version that writes like:
Ref< Derived > d = b.as< Derived >( );

is quite direct, and works well without "b.template ".


Right, it works on your compiler. But a fully conforming compiler is
supposed to reject it, because it does not know whether the < is the less
than sign or a template argument list. Most compilers I've worked with
figure it out in simple cases. So to be conformant, it should be

Ref< Derived > d = b.template as< Derived >( );

and it's exactly the same as my version, except for the function name.
So to avoid the ugly .template notation, you could use

template <class U, class T>
Ref<U> Ref_dynamic_cas t(const Ref<T>&);
Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
2692
by: David B. Held | last post by:
I wanted to post this proposal on c.l.c++.m, but my news server apparently does not support that group any more. I propose a new class of exception safety known as the "smart guarantee". Essentially, the smart guarantee promises to clean up resources whose ownership is passed into the function, for whatever defintion of "clean up" is most appropriate for the resource passed. Note that this is different from both the basic and the...
16
2446
by: He Shiming | last post by:
Hi, I'm having a little bit of trouble regarding pointer casting in my program. I don't understand why the following two cases produce different results. Case 1: IInterface *pInterface = new CImplementation(); pInterface->Method(); Case 2:
33
5094
by: Ney André de Mello Zunino | last post by:
Hello. I have written a simple reference-counting smart pointer class template called RefCountPtr<T>. It works in conjunction with another class, ReferenceCountable, which is responsible for the actual counting. Here is the latter's definition: // --- Begin ReferenceCountable.h ---------- class ReferenceCountable
9
2464
by: Jess | last post by:
Hello, It seems both static_cast and dynamic_cast can cast a base class pointer/reference to a derived class pointer/reference. If so, is there any difference between them? In addition, if I have a derived class object and then upcast it to its base class, which cast operator should I use? Is it static_cast, or, can I simply cast it implicitly without any operator? Does this upcasting remove the derived class portion of the object?...
54
12040
by: Boris | last post by:
I had a 3 hours meeting today with some fellow programmers that are partly not convinced about using smart pointers in C++. Their main concern is a possible performance impact. I've been explaining the advantages of smart pointers endlessly (which are currently used in all our C++ software; we use the Boost smart pointers) as I'm seriously concerned that there is a shift to raw pointers. We are not developing system software but rather...
5
2733
by: johanatan | last post by:
Does anyone know the reasons for the lack of an implicit casting operator in any greater depth than: A. Automatic conversion is believed to be too error prone. (from the FAQ at the bottom of: http://www.boost.org/libs/smart_ptr/shared_ptr.htm) Can anyone say specifically what about the implicit conversion would be dangerous? I can think of a few things that would require care about usage of smart pointers with implicit conversions,...
9
3470
by: Taras_96 | last post by:
Hi everyone, I was experimenting with static_cast and reinterpret cast #include <iostream> struct A1 { int a; }; struct A2 { double d; }; struct B : public A1, A2
50
4531
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): //------------------------------------------------------------------ template<typename Data_t> class SmartPointer { Data_t* data; void(*deleterFunc)(Data_t*);
4
3047
by: Wally Barnes | last post by:
Can someone help a poor C++ programmer that learned the language before there was a standard lib .. etc ? Basically I have two classes that look something like below: template <class T> class ListLogic { public: struct LogicBase {
0
9846
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9685
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10580
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10277
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9413
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7817
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5674
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5853
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3126
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.