多态下的特例:构造函数
1.多态实现
可以同通过继承虚函数的方式实现多态。如:
#include <iostream>
class A{
private:
virtual void TestA();
public:
A(){}
~A(){}
void printA();
virtual void test_1(){std::cout<<"in A::test_1()\n";}
void call_printA();
};
class B: public A{
public:
B(){}
~B(){}
void printA();
void test_1()override{std::cout<<"in B::test_1()\n";}
void TestA() override;
};
void A::printA(){std::cout<<"In A::printA()!\n";}
void A::call_printA(){printA();TestA();}
void A::TestA(){std::cout<<"In A::TestA()\n";}
void B::printA(){std::cout<<"In B::printA()!\n";}
void B::TestA(){std::cout<<"In B::TestA()\n";}
int main(){
A *b = new B();
b->printA();//调用A::printA(),输出:In A::printA()!
b->test_1();//输出:in B::test_1()
b->call_printA();//输出:In A::printA()! In B::TestA()
}
B类继承了A类,且通过虚函数test_1()
实现了多态。b指针的类型为A,通过虚函数实现了多态,所以把b->printA()
调用子类的函数,但是A类中printA()
不是虚函数,所以b->printA()
输出了A类中的printA()
,还可以通过第三方成员函数调用实现多态,如b->call_printA()
分别调用了A::printA()
和B::TestA()
,尽管调用了b->call_printA()
,但是绑定的对象本身没有改变,所以还是能够实现多态。
2.构造函数中调用到的函数不能实现多态
构造函数先调用父类构造函数,此时子类构造函数还没有调用,此时,回调用父类中的函数。
#include <iostream>
class A{
private:
virtual void TestA();
public:
A(){call_printA();}
~A(){}
void printA();
virtual void test_1(){std::cout<<"in A::test_1()\n";}
void call_printA();
};
class B: public A{
public:
B(){std::cout<<"B construction!";}
~B(){}
void printA();
void test_1()override{std::cout<<"in B::test_1()\n";}
void TestA() override;
};
void A::printA(){std::cout<<"In A::printA()!\n";}
void A::call_printA(){printA();TestA();}
void A::TestA(){std::cout<<"In A::TestA()\n";}
void B::printA(){std::cout<<"In B::printA()!\n";}
void B::TestA(){std::cout<<"In B::TestA()\n";}
int main(){
A *b = new B();//输出:In A::printA()! In A::TestA(),B construction!
b->printA();//输出In A::printA()!
b->test_1();//in B::test_1()
b->call_printA();//输出:In A::printA()! In B::TestA()
}
构造函数先调用父类A的构造函数,此时,构造函数中调用A::call_printA()
,进而调用A::printA()
和A::TestA();
,此时不会表现出多态的特性,B类还没有完成构造,然后调用B类构造函数输出B construction!
,接下来输出和1中相似了。
所以父类构造函数中不会实现多态!!!