Assigning one class object to another class object.

Hi,

I have two classes derived from same class as below:

class Base
{
//member functions
};

class Derived1 : public Base
{

};

class Derived2 : public Base
{

};

Now I want to assign Derived2 class object to Derived1 class object. How do i do it? And what type of casting is this called?

Thank you.
It's not any type of casting. You basically just take advantage of function overriding.
1
2
3
4
5
Derived2 &Derived2::operator=(const Derived1 &right){
    this->Base::operator=(right);
    //Your assignments here.
    return *this;
}
There's no ned for that! It's possible with nothing but a reference-shematics operator= for the class Base. Since references are basicly pointers that act like objects, polymorphism works, so both derived1 and Derived2 can be assigned to eachother and Base.
What? Can you give an example?
That only works if the assignment operator takes a reference to the base class. This doesn't generally make sense; you can't clone a cat into a dog.
Hi All,

There is one more restriction which I forgot to mention. Apologies for that.

The Base and the two Derived classes are all generated by some ASN compiler. So I cannot make any changes to the class. Now how do I get this done without making any changes to any of the classes?
Hi All,

There is one more restriction which I forgot to mention. Apologies for that.

The Base and the two Derived classes are all generated by some ASN compiler. So I cannot make any changes to the class. Now how do I get this done without making any changes to any of the classes?

I think I can use reinterpret_cast. But I am not sure how safe is that?

Kindly help.
@vinaynaikwad: Dind't you hear me? You can use the predefined assignment operator! EVEREY assignment operator shall take a reference, so it MUST work!
@Telion: Really?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct animal
{
};

struct dog: animal
{
};

struct cat: animal
{
};

int main()
{
	dog Dog;
	cat Cat;
	swap<animal>(Cat, Dog);
}
Last edited on
@viliml

You mean the following:

Derived1 d1;
Derived2 d2;

d1 = d2; ???
Yes, precisly! It must work!
@viliml
Dog = Cat; in your example does not work.
That is, it may compile (I'm not sure), but only animal::operator=() will get called, thus only animal's members will get set. dog's members will be left in an inconsistent state.
Can you show us the base class? if it has setter and getter functions you could just use those, or if its variables aren't private that works too.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>

class animal
{
public:
    void noise()
    {
        std::cout << health << " / " << speed << std::endl;
    }

    void setHealth(int hp){health = hp;}
    void setSpeed(int spd){speed = spd;}
    int getHealth(){return health;}
    int getSpeed(){return speed;}
private:
    int health;
    int speed;
};

class cat: public animal
{

};

class dog: public animal
{

};

void copyAnimal(animal& left, animal& right)
{
    left.setHealth(right.getHealth());
    left.setSpeed(right.getSpeed());
}

int main()
{
    cat Cat;
    Cat.setHealth(9);
    Cat.setSpeed(10);

    dog Dog;
    Dog.setHealth(15);
    Dog.setSpeed(20);

    Cat.noise();
    Dog.noise();

    copyAnimal(Dog, Cat);
    std::cout << std::endl;
    Dog.noise();
}
@viliml
That doesn't work. Gives casting error.

@Zephilinox
My base class doesn't have any set/get methods. And the derived classes have one public variable each whose enum value is same.
I have Derived2 object which I need to pass to a function that accepts Derived1 object. I tried using reinterpret_cast as below:

Derived1 supports 3 enum values: locked, shuttingdown and unlocked.
Derived2 supports 2 enum values: locked and unlocked.

Derived1* d1 = reinterpret_cast<Derived1 *> d2;

But when I dereferenced d1, it had some other value. Like, when d2 had unlocked, after re-interpret casting, d1 was having locked sometimes, unlocked the other time and also shuttingdown sometimes.

You suspect any problem with the way I am using reinterpret_cast?

if d2 doesn't have shuttingdown, then it shouldn't be passed to a function that expects d2, at least I think it shouldn't, because shuttingdown would be undefined if that function were to try and access it.

maybe it simply isn't possible, or has your teacher(?) said otherwise?
@Zephilinox
I got the problem.
Derived1 has these values: locked(0), unlocked(1), shuttingDown(2).
Values in the brackets are corresponding enum values.

Derived2 has: locked(1), unlocked(2).

When I reinterpret_cast d2 to d1, and when d2 is locked(1), the corresponding d1 values would be unlocked(1). And when d2 is unlocked(2), the corresponding d1 afetr casting is shuttingDown(2). Hence the problem is with enum values.

Anyways, reinterpret_cast will get the job done.

But how safe is reinterpret_cast?
But how safe is reinterpret_cast?


Not safe at all. It is effectively you insisting to the compiler that it forget everything it knows and treat an object as if it were a different kind of object, no matter what. No converting is done, no considerations taken. This pattern of bits that five seconds was this kind of object; now pretend it's that kind of object.
Last edited on
reinterpret_cast is the same as making an anonymous union, whose first member is of the type that you are casting from, and the second one is the one you are casting to, then you assign the value of the first type that you want to reinterpret_cast from to the first member, and then use the second member as the reinterpret_casted value.
Last edited on
but only animal::operator=() will get called, thus only animal's members will get set. dog's members will be left in an inconsistent state.
You are trying to assign a cat to a dog, ¿what the hell do you expect to happen?

Now I want to assign Derived2 class object to Derived1 class object.
¿why? They are different things.
You are trying to assign a cat to a dog, ¿what the hell do you expect to happen?
Well, of course in the general case it doesn't make sense, but that's not to say that there are no special cases where operator=() could perform some sort of conversion between objects of different types.
For example, suppose you have Bezier and Circle, which are both kinds of Curves. A Bezier curve has nothing that even remotely resembles a center or a radius, but it can be used to approximate a circle, so it would be nice if you could do that by just doing an assignment.
Topic archived. No new replies allowed.