0

I was looking to create a function that is capable of working with any Derived Object of A. However in this example, I can't seem to be able to use B Object in a function that has a A Typing on it. Is there any way I pass B into the Function?

class A {
public:
    A() {

    }
};
class B :A {
public:
    B() {

    }
};

void function(A a) {
    return;
}

int main(void) {
    B b();
    function(b);
}
  • please include the compiler error message in the question. The simple answer is to pass by reference, but there is more going on in your code that needs to be fixed – 463035818_is_not_an_ai Apr 12 '22 at 18:36
  • 5
    `B b();` is a function, use `B b;`. – HolyBlackCat Apr 12 '22 at 18:36
  • 2
    This is known as the "most vexing parse of C++". Further, you're using private (!) inheritance. That said, your question lacks the actual error. Also, don't use parent/child when referring to classes, because it models an "is a" relation that inverts use in normal language. As a new user here, also take the [tour] and read [ask]. – Ulrich Eckhardt Apr 12 '22 at 18:36
  • 3
    The default privacy of inheritance for a class is `private`. You'll need `class B: public A` for it to be convertible to `A` for purposes of overload resolution. – Nathan Pierson Apr 12 '22 at 18:37
  • Pass by (const?) reference and also make sure the function is able to see the base class by either making it a friend of `B` or preferrably inherit `A` publicly in `B`... – fabian Apr 12 '22 at 18:37
  • My mother can type far better than I can, so the inheritance of typing is not guaranteed. – user4581301 Apr 12 '22 at 18:39
  • Also, in this example, `A` and `B` don't have any actual methods or content and `function` isn't doing anything, but for your real code where there's actual behavior you'll probably some stuff in `A` `virtual` – Nathan Pierson Apr 12 '22 at 18:44

2 Answers2

0

I've commented on the fixes needed inline:

class A {
public:
    A() {}
};

class B : public A {        // public inheritance or A will be an inaccessible base of B
public:
    B() {}
};

void function(const A& a) { // take a reference to an A to avoid copy-slicing
    // ... work with the A part of the object you reference with `a`
}

int main() {                // void not needed (but not an error as such)
    B b;                    // not a function declaration anymore
    function(b);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

Actually you are lucky. You made two mistakes that caused passing b to the function fail, while in fact without that other mistakes you can pass b to the function but it would do the wrong thing silently.

First the two mistakes: B b(); declares a function. To declare a default constructed B you write B b;. Then B inherits privately, hence you cannot convert a B to an A. Thats what the error your code causes have told you.

However, after fixing those (and removing user declared constructors taht shouldnt be there when they do nothing)...

class A {};
class B : public A {};

void function(A a) {}

int main(void) {
    B b;
    function(b);   // object slicing !!
}

This code compiles without errors, but usually it does the wrong thing!

Any B can be converted to an A because the inheritance is public, but what happens is object slicing: What is object slicing?. If B had any members not in A then they would all be lost when passing it to function. Its not an issue here because neither A nor B have any members, but in general you want to avoid objects to get sliced.

TL;DR: References / pointers are needed for polymorphism. Pass by (const) reference:

void function(const A& a) {}    // does not modify a
void function(A& a) {}          // modifies a
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185