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( ); }
}; 5 3153
"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.
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
"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
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 ".
"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>&); This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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:
|
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
|
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?...
|
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...
| |
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,...
|
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
|
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*);
|
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 {
|
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...
|
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,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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...
|
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...
|
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...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
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...
| |