About Base class call subclass function

like this code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
class A{
public:
  A(){show();}
  virtual void show(){std::cout<<"A::Show()"<<std::endl;}
  void test(){show();}
};

class B : public A{
public:
  B(){}
  virtual void show(){std::cout<<"B::Show()"<<std::endl;}
};

int main(){
  B* b = new B();
  b->test();
  return 0;
}



this code output:
A::Show()
B::Show()

Why?Is it because the virtual function address rewritten by B has not been mapped to A's virtual function table when calling A's constructor?
If I want to call B's show() in A(),how should I do.
Last edited on
Please use code tags. Also, main() returns an int.

The line
B* b = new B();
will yield output
A::Show()

because the elements and constructor of the superclass A are created/called when creating an object of type B.

The line
b->test();
will yield output
B::Show()

since an object of type B inherits the public function test, which calls the function show() - and since that function is declared virtual in A it can use the runtime polymorphic version from B. You may like to try seeing what happens if you remove the "virtual" in the declaration of A.
@lastchance ,thanks for your advice.

What I really want to do is:
Define a rule step in A. Any class using A must call a function, but this function can be implemented by the inherited class.
For example,The machine produced by a factory must be provided with instructions. The factory produces many types of machines, and the instructions for each type of machine are different.So,the factory stipulates that the product must have a manual,but the instructions for each machine are prepared by the corresponding department itself,the factory does not want each product line to skip the step of writing instructions,What should it do?
What should it do?

Isn't that what you are doing already with your "Show()" function?
No,the final code in main()
1
2
3
4
5

int main(){
  B* b = new B();
  return 0;
}

I want this code's output "B::Show()",The show() is called only once when create subclass objects ,I want to prevent class B's developers from forgetting to call the show function.
Do you perhaps mean this:
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
#include <iostream>

class AbstractMachine {
public:
  void manual() {
      std::cout<<"Manual\n";
      show();
  }
private:
  virtual void show() = 0;
};

class Printer : public AbstractMachine
{
public:
  Printer() = default;
private:
  void show() {std::cout<<"B::Show()"<<std::endl;}
};

class Stabler : public AbstractMachine
{
public:
  Stabler() = default;
};

int main(){
  Printer b;
  b.manual();
  AbstractMachine a; // Error: type is abstract
  Stabler c; // Error: type is abstract (no show)
}
No, AbstractMachine is not a pure virtual class. Show() needs to provide a default implementation, and AbstractMachine calls the show() in the constructor.Perhaps this cannot be achieved in syntax. Is it possible to achieve this through other methods?For example, there is a table that is specifically responsible for recording subclasses inherited from A, or a constructor that allows A to identify whether it was triggered because it was inherited by others when it was created
Last edited on
The problem is that when the A constructor runs the B object has not been fully constructed yet. If B had member variables they wouldn't have been initialized yet. If constructors of a base class could call virtual functions of derived classes it would be too easy to accidentally access uninitialized variables of the derived class. That's why the virtual dispatch is disabled in constructors.

KaiTang wrote:
For example,The machine produced by a factory must be provided with instructions. The factory produces many types of machines, and the instructions for each type of machine are different.So,the factory stipulates that the product must have a manual,but the instructions for each machine are prepared by the corresponding department itself,the factory does not want each product line to skip the step of writing instructions,What should it do?

Can't the "factory" be responsible for writing the instructions by calling the method after the "machine" has been created?
@Peter
For example, this instructions is mandatory,Any "machine" should call show() when it is created whether it's your own or provided by factory.Since "machine" is a user-defined class, there is no guarantee that it will call the show() function when it is implemented.So So I hope that factory can take some measures to make the machine enforce show().Just like the firewall must be set for security, you can use the configuration that comes with the system, or you can modify the configuration yourself, but do not close the firewall.The priority configured is "machine" > "factory".
Last edited on
KaiTang,
Please stop editing your original post. It makes subsequent replies difficult to follow. Also, keep your example simple.

What you are asking is if the following code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
class A{
public:
  A(){show();}
  virtual void show(){std::cout<<"A::Show()"<<std::endl;}
};

class B : public A{
public:
  B(){}
  virtual void show(){std::cout<<"B::Show()"<<std::endl;}
};

int main(){
  B* b = new B();
}

could be modified to output "B::Show()", rather than "A::Show()".
Last edited on
yes @lastchance
I don't think you can - for the reason given by @Peter87 above. B's definition isn't complete, so A wouldn't be able to call a member of it.

You could force the writer of B to have to write a show() member function by @Keskiverto's suggestion: virtual void show() = 0; if he does call it ... but I don't think you could force him to call it.
Last edited on
Perhaps via composition:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

class B {
public:
  void show()
  { std::cout<<"blah blah\n"; }
};

class A{
public:
  A(B* f = nullptr)
  : b{f}
  {
      if ( b ) b->show();
      else std::cout<<"Default\n";
  }
private:
  B* b;
};

int main(){
  A a;
}

Now the stuff from factory is used by A and A does call show, so B must provide it.
Although this is OK, the inheritance relationship is wrong. B must inherit from A. @keskiverto
Topic archived. No new replies allowed.