#include <iostream>
class A{
public:
A(){show();}
virtualvoid show(){std::cout<<"A::Show()"<<std::endl;}
void test(){show();}
};
class B : public A{
public:
B(){}
virtualvoid 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.
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.
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?
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.
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
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".
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();}
virtualvoid show(){std::cout<<"A::Show()"<<std::endl;}
};
class B : public A{
public:
B(){}
virtualvoid show(){std::cout<<"B::Show()"<<std::endl;}
};
int main(){
B* b = new B();
}
could be modified to output "B::Show()", rather than "A::Show()".
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: virtualvoid show() = 0; if he does call it ... but I don't think you could force him to call it.
#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.