0

I want to call B::func2(int x, int y) in A::func1(x), how to declare them?

class A {
public:
    void func1(int x);
    virtual void func2(int x, int y); // do not need implement in A
};

class B : public A {
public:
    void func2(int x, int y) override; // override
};

void A::func1(int x) {
    int y;
    func2(x, y); // I want to use the version of A's subclass
}

int main()
{
    B b;
    b.func1(x); // call A::func1(x) first then call B::func2(x, y)
}

It won't compile, instead the following error message is shown

> clang++ test.cpp -std=c++11

Undefined symbols for architecture x86_64:

"typeinfo for A", referenced from:

 typeinfo for B in test-bbac7f.o

"vtable for A", referenced from:

 A::() in test-bbac7f.o

NOTE: a missing vtable usually means the first non-inline virtual member > function has no definition.

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

TobiMcNamobi
  • 4,687
  • 3
  • 33
  • 52
Yriuns
  • 755
  • 1
  • 8
  • 22
  • 4
    Doesn't that already happen with the code you show? How have you tested it? What results do you get, and what results did you expect? – Some programmer dude Jul 20 '17 at 10:23
  • 2
    Why do you want to call `B::func2()` in `A::func1()`? What do you require if the actual object is not a `B`? – Peter Jul 20 '17 at 10:23

2 Answers2

2

// call A::func1(x) first then call B::func2(x, y)

It's exactly what will happen in your case. See at Coliru.

Basically, that's what virtual calls are about. Since func2 is marked "virtual", when it's invoked A::func1, the call will go though vtable, hence an overriden method B::func2 will be called.

It's vice versa: if you want A::func1 to invoke A::func2, you would have to write it explicitly:

void A::func1(int x) {
    int y;
    A::func2(x, y); // explicitly tell to use A's version; otherwise the overriden method from the subclass is invoked.
}

P.S. This answer advises to make A::func2 pure virtual. This could make sense, if you don't plan to use the implementation of A::func2. If, for whatever reason, you need to have some functional code within A::func2 as well, then typical pattern is to add a call to A::func2 in a derived class, like this

void B::func2(int x, int y) {
  A::func2(x, y);
  // do something specific for B
}
Vasiliy Galkin
  • 1,894
  • 1
  • 14
  • 25
1

Couple of things :

1.) Make A::func2 pure virtual by appending =0;, OR define its body using braces {} (note that it can be left empty).

2.) Define the body of B::func2 using braces {} (again, can be left empty).

You can't call a function which is not defined at first place.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79