2

First off, I'm not totally sure how to Title my question.

I have a question about inheritance.

Let's say I make a class called Class_A:

class Class_A
{
    public:
        int a;
        int b;
};

Then, I make Class_B, which inherits Class_A:

class Class_B : public Class_A
{
    public:
        int c;
        int d;
}

Then I make an instance of Class_B:

Class_B my_class_b;

Now, I have a function that takes an instance of a Class_A, changes it, and then returns a Class_A:

Class_A func (Class_A which)
{
    which.a += 20;
    which.b -= 20;

    return which;
}

What I'm trying to accomplish is, I want to be able to pass any Class_A into the function, and then assign the changes back to whatever was passed into it.
I tried this:

Class_A temp = func (my_class_b);
my_class_b = temp;

Passing my_class_b in for a Class_A works, but assigning it back to my_class_b doesn't.

I get a:

no match for 'operator=' in 'my_class_b = temp'

What is the best way to go about doing this? Thanks for any help.

Justin Lloyd
  • 123
  • 3
  • 11
  • 4
    An object of class `A` is not an object of class `B`, even if `B` inherits from `A` they are still different and distinct types. You have to pass the `B` instance by reference (and return a reference) or as a pointer (and return pointer). You should also read about [object slicing](http://en.wikipedia.org/wiki/Object_slicing). – Some programmer dude Aug 03 '14 at 17:14
  • 1
    `static_cast(my_class_b) = temp;` Though it's not clear why you are using inheritance in the first place. It's clearly not for polymorphism - `func` very effectively inhibits that. It would be easier for `Class_B` to contain a member of `Class_A`, rather than derive from it. – Igor Tandetnik Aug 03 '14 at 17:15
  • reference parameter would probably be better, instead of return value – sp2danny Aug 03 '14 at 17:19
  • 1
    Change parameter type to `Class_A&` and don't return anything by value, as this will result in object slicing. – Neil Kirk Aug 03 '14 at 17:19
  • @IgorTandetnik How does that cast help anything? It's implicit. – Neil Kirk Aug 03 '14 at 17:19
  • 1
    @NeilKirk No idea what you are talking about. What's implicit? Anyway, here's a [working example](http://ideone.com/cGdZZq). So yes, that *explicit* cast helps something. – Igor Tandetnik Aug 03 '14 at 17:23
  • @IgorTandetnik You are right, I got confused. I thought it would inherit assignment operator that takes class A. – Neil Kirk Aug 03 '14 at 17:26
  • @NeilKirk Perhaps this would make it clearer. That assignment with a cast is equivalent to `my_class_b.Class_A::operator=(temp);` – Igor Tandetnik Aug 03 '14 at 17:26
  • I'd thought about having `Class_B` contain a member of `Class_A`, but wanted to see if I could make this work. The reason I'm doing this is because of how it works in the game I'm programming. I have a class called `Movable_Object`, which is anything that can have coordinates, velocity, etc. Then the classes `Player`, `Monster`, `NPC` are all `Movable_Objects`. The function in question is `Check_WorldMap_Collision (Movable_Object which)`. I want the player, monsters, and npcs to check if they are hitting into a tile, and then update their coordinates and velocity if they hit something. – Justin Lloyd Aug 03 '14 at 17:27
  • @sp2danny _better_ in almost all cases. **required** in polymorphic cases. – underscore_d Feb 16 '16 at 16:34

3 Answers3

3

change func to:

void func (Class_A& which)
{
    which.a += 20;
    which.b -= 20;
}

and use it like

func(my_class_b);
sp2danny
  • 7,488
  • 3
  • 31
  • 53
1

There is no single best way to do this.

When calling func with an object of class B, the object is first converted to type A (the so-called slicing problem), which may already be unacceptable. So one way to fix your code is to fix the way you use your func function.

For example, make it a public virtual member function:

class Class_A
{
    public:
        virtual void func() {...}
    ...
}

my_class_b.func(); // instead of Class_A temp = func (my_class_b); my_class_b = temp;

Another way: make func modify an existing object, instead of making a new object:

void func(A& object) {...}
...
func(my_class_b); // instead of Class_A temp = func (my_class_b); my_class_b = temp;

If you want to use the assignment syntax, and you are sure that slicing is not a problem for your code (unlikely), you can define an assignment operator for class B:

class B {
    B& operator=(A object) {a = object.a; b = object.b; return *this;}
    ...
}

Or (better) add a way to construct a B from A:

class B {
    B(A object): A(object), c(0), d(0) {}
    ...
}
Community
  • 1
  • 1
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • Assigning an operator is something I've never done before, but need to learn. However, the method posted about modifying an existing object seems like the best way to go for me. Thanks for the ideas. – Justin Lloyd Aug 03 '14 at 17:44
1

One way is : You'll have to overload the operator in Class_b to copy the values of Class_a. The second way is: Use static_cast ( temp ) but this method is not always safe.

Ali Mohyudin
  • 242
  • 2
  • 10