upcasting with smart pointers

M

mati-006

Hi,
I think the code will be the best way to explain what I mean:

#include "arglib/arg_shared.h"
class base {
public:
base() {}
virtual ~base() {}
};

class derived : public base {
public:
derived() {}
~derived() {}
};

int main()
{
arg::counted_ptr<base> bsp;
arg::counted_ptr<derived> dsp(new derived);
base * bp;
derived * dp(new derived);

bp=dp;
bsp=dsp;
}

The smart pointers I'm using are documented here:
http://www.octopull.demon.co.uk/arglib/class_arg__counted_ptr.html

The problem:
bp=dp; - works
bsp=dsp; - doesn't work, compile error:

test.cpp: In function `int main()':
test.cpp:16: error: no match for 'operator=' in 'bsp = dsp'
arglib/arg_shared.h:312: error: candidates are:
arg::counted_ptr<pointee_type>&
arg::counted_ptr<pointee_type>::eek:perator=(const
arg::typed_reference<pointee_type>&) [with pointee_type = base]
arglib/arg_shared.h:324: error:
arg::counted_ptr<pointee_type>&
arg::counted_ptr<pointee_type>::eek:perator=(const
arg::counted_ptr<pointee_type>&) [with pointee_type = base]
make: *** [test.o] Error 1

Question is, what is the best way to deal with upcasting using smart
pointers? Or maybe I'm using not-so-smart pointers and the upcasting
thing is possible with properly written smart pointers?
 
G

Gianni Mariani

mati-006 wrote:
....
Question is, what is the best way to deal with upcasting using smart
pointers? Or maybe I'm using not-so-smart pointers and the upcasting
thing is possible with properly written smart pointers?

The "smart" pointers need to be able to deal with this. This is usually
accommodated by overloading the copy constructor and the assignment
operator with template versions.
 
J

JoeC

mati-006 said:
Hi,
I think the code will be the best way to explain what I mean:

#include "arglib/arg_shared.h"
class base {
public:
base() {}
virtual ~base() {}
};

class derived : public base {
public:
derived() {}
~derived() {}
};

int main()
{
arg::counted_ptr<base> bsp;
arg::counted_ptr<derived> dsp(new derived);
base * bp;
derived * dp(new derived);

bp=dp;
bsp=dsp;
}

The smart pointers I'm using are documented here:
http://www.octopull.demon.co.uk/arglib/class_arg__counted_ptr.html

The problem:
bp=dp; - works
bsp=dsp; - doesn't work, compile error:

test.cpp: In function `int main()':
test.cpp:16: error: no match for 'operator=' in 'bsp = dsp'
arglib/arg_shared.h:312: error: candidates are:
arg::counted_ptr<pointee_type>&
arg::counted_ptr<pointee_type>::eek:perator=(const
arg::typed_reference<pointee_type>&) [with pointee_type = base]
arglib/arg_shared.h:324: error:
arg::counted_ptr<pointee_type>&
arg::counted_ptr<pointee_type>::eek:perator=(const
arg::counted_ptr<pointee_type>&) [with pointee_type = base]
make: *** [test.o] Error 1

Question is, what is the best way to deal with upcasting using smart
pointers? Or maybe I'm using not-so-smart pointers and the upcasting
thing is possible with properly written smart pointers?

Here is some work I have done...

class hunit{

unit * p;
int * cnt;
public:
hunit() : cnt(new int(1)), p(new unit) {}
hunit(char);
hunit(const hunit& u) : cnt(u.cnt), p(u.p) {++*cnt;}
hunit& operator = (const hunit&);
hunit(std::istream);
~hunit();
void move();
void attack();
void display();
};

#include "hunit.h"
#include "air.h"
#include "sea.h"

hunit::hunit(char n){

switch(n){
case 'u':
p = new unit;
break;
case 'a':
p = new air;
break;
case 's':
p = new sea;
break;
}

cnt = new int(1);

}

hunit& hunit::eek:perator = (const hunit& h){
++*h.cnt;
if(--*cnt == 0){
delete p;
delete cnt;
}
p = h.p;
cnt = h.cnt;
return *this;
}


hunit::hunit(std::istream){

}

hunit::~hunit(){
if(--*cnt == 0){
delete p;
delete cnt;
}
}

void hunit::move(){
p->move();
}

void hunit::attack(){
p->attack();
}

void hunit::display(){
p->display();
}


class unit{
protected:
int locx;
int locy;

int atk;
int dfce;
void create();
public:
unit();
unit(std::istream);
virtual ~unit(){};
virtual unit* copy() const;
virtual void move();
virtual void attack();
virtual void display();
};


#include"unit.h"

unit::unit(std::istream in){
create();
}

unit::unit(){
create();
}

void unit::create(){
locx = 0;
locy = 0;

atk = 0;
dfce = 0;
}

void unit::move(){
std::cout<<"Moving"<<std::endl;
}


void unit::attack(){
std::cout<<"Charge! \n";
}

void unit::display(){
std::cout<<"Here I am \n";
std::cout<<locx<<" "<<locy<<"\n";
}

unit* unit::copy() const{
return new unit(*this);
}
 
M

Moonlit

Hi,

From my weak/strong smartptr class, I have something like this:

template<class A>
MSRefPtr<T>& operator=( const MSRefPtr<A>& SRefPtr )
{
T *TmpPtr = this->Ptr;
this->Ptr = SRefPtr.Ptr;
if( this->Ptr ) this->Ptr->IncCnt();
if( TmpPtr ) TmpPtr->DecCnt();

return *this;
}

For instance this would be valid for T as base type and A as derived (but
not the other way around).

You probaly need something similar.


Regards, Ron AF Greve

http://moonlit.xs4all.nl
 

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

No members online now.

Forum statistics

Threads
473,983
Messages
2,570,187
Members
46,747
Latest member
jojoBizaroo

Latest Threads

Top