Casting smart pointers

E

Ernesto

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
 
G

Greg Comeau

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() ?

I'm curious of your tradeoffs of choosing doing this over just
using a std::string?
 
R

Rolf Magnus

Ernesto said:
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() ?

Basically yes, but not in conjunction with printf, because it is a function
with a variable argument list. Those functions are not type safe, meaning
that the compiler doesn't implicitly know that it has to convert your
Pointer<char> into a char*. You'd have to use a cast, like:

printf("Message: %s\n", static_cast<char*>(charPointer));

You can do that by implementing an operator char* for your class. Something
like:

template <typename T>
class Pointer
{
public:
operator T*()
{
return ptr_;
}
private:
T* ptr;
};

However, such a conversion operator is dangerous, since it could lead to
subtle errors, and it's usually better to stick with the getData() member
function.
 
O

Oliver Gerlich

Rolf said:
Ernesto wrote:

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() ?


Basically yes, but not in conjunction with printf, because it is a function
with a variable argument list. Those functions are not type safe, meaning
that the compiler doesn't implicitly know that it has to convert your
Pointer<char> into a char*. You'd have to use a cast, like:

printf("Message: %s\n", static_cast<char*>(charPointer));

You can do that by implementing an operator char* for your class. Something
like:

template <typename T>
class Pointer
{
public:
operator T*()
{
return ptr_;
}
private:
T* ptr;
};

However, such a conversion operator is dangerous, since it could lead to
subtle errors, and it's usually better to stick with the getData() member
function.

Just out of curiosity, would the overloaded char* cast operator work
better when using streams
(like cout << "Message: " << charPointer << endl) instead of printf()?

Oliver Gerlich
 
I

Ioannis Vranos

Oliver said:
Just out of curiosity, would the overloaded char* cast operator work
better when using streams
(like cout << "Message: " << charPointer << endl) instead of printf()?


Yes, although providing an operator<<(ostream &, yourclass &) overload
would be better.
 
E

Ernesto

Hi:

Thanks a lot for your tips!

I am developing a library and I was thinking about implementing all my
classes using my Pointer class template, by example, using:

void Array::AddElement(Pointer<T> aElement);
Pointer<Array> Windows::GetComponents();

instead of

void Array::AddElement(T* aElement);
Array* Widget::GetInnerWidgets();

Do you think it is a good idea? Or should I use my reference count
Pointer internally (à la "copy on write" mechanism as in the string
classes) and provide classical pointers in my API ? If it is a good
idea, how should I handle the circular references?

Best regards



Ernesto
 
R

Rolf Magnus

Ioannis said:
Yes, although providing an operator<<(ostream &, yourclass &) overload
would be better.

Rather an operator<<(ostream&, const yourclass&).
 
E

Ernesto

Hi:

I used a char* just as an example. I am actually implementing a
reference count smart pointer and I want it to be casted to the
specified template instantiation, id est, if I define:

Pointer<int> intPtr = new int[10];

int* otherPtr = intPtr;

or

Pointer<char> charPtr = new char[10];
char* otherCPtr = charPtr;


both should work.

:)

Best regards



Ernesto
 
G

Gianni Mariani

Ernesto said:
Hi:

Thanks a lot for your tips!

I am developing a library and I was thinking about implementing all my
classes using my Pointer class template, by example, using:

void Array::AddElement(Pointer<T> aElement);
Pointer<Array> Windows::GetComponents();

instead of

void Array::AddElement(T* aElement);
Array* Widget::GetInnerWidgets();

Do you think it is a good idea? Or should I use my reference count
Pointer internally (à la "copy on write" mechanism as in the string
classes) and provide classical pointers in my API ? If it is a good
idea, how should I handle the circular references?

Circular references need to be avoided by design. The correct use of
"weak" pointers is needed to ensure the correctness of the design.

When using "Austria C++" (shameless plug), I find that for reference
counted objects, there are almost no cases where non-smart pointers are
used. This is important for making sure that the code is also exception
safe.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top