473,472 Members | 2,155 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Downcast with smart pointers?

Hello,

I'm having a design issue that I can't solve. I'm getting from a
network a stream of data, which is a http message (my program is
neither a client or server, it just catches messages over the network)

For this I have a class http_message with the usual methods (to access
header, fields, etc)
I also have two other classes, http_request and http_response, which
should be used depending on the type of message received. These two
classes derive from http_message, and contain some more helper
methods. They don't have any data (as it uses the data from the base
class)

And this is my problem. At some point I'd like to instantiate a
request or response data, but I don't know how to do it, as I'm using
smart pointers instead of plain pointers (the program uses several
threads, and these objects are accessed by many of them)

If I were using simple pointers, I'd do a dynamic_cast, but how is
this done with a smart pointer? (I'm using the CountedPtr available in
many places) I thought about using a copy constructor in the request
and response classes, taking a message as parameter, and initializing
the object from there, but that doesn't look very well, does it?

Any comment about how to proceed in this case? Any advice/example will
be greatly appreciated.

Thanks.

Jul 21 '07 #1
3 5365
Hi,
Then inside this function, I'd need to instantiate the correct object.
But how to do it? I tried:
SmartPtr<HttpResponseresp = msg;
But of course doesn't work. If I were using normal pointers, then I'd
do dynamic_cast<HttpResponse*>(msg) and everything ok.

It doesn't work because there is no implicit conversion from
SmartPtr<HttpMsgto SmartPtr<HttpResponse>. One possible way to do it
is to create a derived class from the standard smart pointer (of
course, if you have control of the pointer implemetation, do it
directly on its implementation), and add

a member template function in the auto_ptr implementation, similar to
this

template <class NEW_T>
operator auto_ptr<NEW_T>
{
return auto_otr<NEW_T(dynamic_cast (NEW_T *(this->get ()));

}
Correct me if I wrong, but in that case I'd get two separate smart
pointers, wouldn't I? I'd prefer that both pointers share the
reference count, otherwise it could be very dangerous (if original
smart pointer's count reach zero, then pointer would be deleted)
Unless of course that I do a deep copy of the inner object, but that
wouldn't be performance wise..

This is what I've trying to do. I took the implementation from here,
which is simple enough and fits my purposes (at least it did before
getting here!)

http://www.josuttis.de/libbook/cont/countptr.hpp.html

And to add support for dynamic_cast I made some additions:

Added this friend function:

template<class U>
friend
CountedPtr<UDynamic_Cast(CountedPtr<T>& sp)
{
U* upcast = dynamic_cast<U*>(sp.ptr);

if (upcast)
return CountedPtr<U>(upcast, sp.count);
else
return CountedPtr<U>;
}

For this to work, I had to create a new constructor which not only
takes a pointer, but an already existing counter. This way, I avoid
what I mentioned you above.

Unfortunately, it doesn't work. I'm getting an error saying this
(using VC6)

none of the 7 overloads can convert parameter 1 from type 'const class
CountedPtr<class HttpMsg>'

Also, now I'm getting another surprise: If I have this method
void foo(const CountedPtr<HttpMsgmsg);

Then if I have an instance:
CountedPtr<HttpRequestreq(new HttpRequest);

Then I'd like to do this:
foo(req);

But it doesn't work either! Why is that? Shouldn't upcasting work?

Thanks again.

Jul 22 '07 #2
You can't change the type of an object. When you instantiate a HttpMsg, you
can't change the type to a HttpRequest or HttpResponse after that.

You can make a 'factory', a function that parses a buffer and gives you
either a HttpRequest or a HttpResponse:

SmartPtr<HttpMsgcreateMessage(const std::string& buffer)
{
// ... parse buffer...
if (isRequest)
return SmartPtr<HttpMsg>(new HttpRequest(buffer));
else
return SmartPtr<HttpMsg>(new HttpResponse(buffer));

}
Yes, I'm doing this now to create the appropriate object. But my
problem is that I'm passing this to a method that takes either request
or responses, so its parameter is a HttpMsg. And now I'm having two
problems: neither upcasting nor downcasting seem to work!
In some situations, I'd like to pass some of these objects to a
function, so assuming I have a generic function (because it could
either accept a request or response):
void foo(const SmartPtr<HttpMsg>& msg);
Then inside this function, I'd need to instantiate the correct object.
But how to do it? I tried:
SmartPtr<HttpResponseresp = msg;
But of course doesn't work. If I were using normal pointers, then I'd
do dynamic_cast<HttpResponse*>(msg) and everything ok.

Get the raw pointer and do a dynamic_cast. Or use another smart pointer
like boost::shared_ptr (which is tr1::shared_ptr), that has a dynamic_cast
replacement: dynamic_pointer_cast<>.
Yes, unfortunately I'd like to make my own, for simplicity purposes,
and for space. Also, some environments I use don't have std library
available.
Well, smart pointers transfer ownership. If your foo() function here
doesn't store the HttpMsg object, it could take a const reference instead:

void foo(const HttpMsg& msg);
That would be one option. I assume it is safe enough.. but my problem
is that these messages are passed from one side to another, including
different threads..

Thanks!

Jul 22 '07 #3
On 22 Jul, 12:35, alebc...@gmail.com wrote:
Yes, but for the moment, I'd feel happy if I made it work even for
single thread environments.
I would recommend you get hold of a library with std::tr1::shared_ptr
for your compiler. It will be in the next C++ standard.
I don't know however where you can get such a library.. Only info I
can find is:

http://www.amazon.com/Standard-Libra.../dp/0321412990

Point is that smart pointers are tricky to get right, so before
rolling your own see what the current solutions are. There is a long
history of smart pointers and no perfect solution and many many subtle
problems.

(Someone may want to hint very similar lib to std::tr1::shared_ptr . I
aint going to though ;-))

regards
Andy Little

Jul 22 '07 #4

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

Similar topics

9
by: christopher diggins | last post by:
I would like to survey how widespread the usage of smart pointers in C++ code is today. Any anecdotal experience about the frequency of usage of smart pointer for dynamic allocation in your own...
27
by: Susan Baker | last post by:
Hi, I'm just reading about smart pointers.. I have some existing C code that I would like to provide wrapper classes for. Specifically, I would like to provide wrappers for two stucts defined...
8
by: Axter | last post by:
I normally use a program call Doxygen to document my source code.(http://www.stack.nl/~dimitri/doxygen) This method works great for small and medium size projects, and you can get good...
8
by: | last post by:
#include <iostream> using namespace std; class Base { public: Base() {} ~Base() {} };
92
by: Jim Langston | last post by:
Someone made the statement in a newsgroup that most C++ programmers use smart pointers. His actual phrase was "most of us" but I really don't think that most C++ programmers use smart pointers,...
33
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...
54
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...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
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,...
1
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...
0
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...
0
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...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
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 ...

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.