#include<iostream> //实现vptr指针初始化问题 using namespace std; class Father { public: Father (int f) { this->f=f; //print(); } virtual void print() { cout<<" 我是父类函数 "; } private: int f; protected: }; class Child:public Father { public: Child(int c=0):Father(5) { //this->c=c; //print(); } virtual void print() { cout<<" 我是子类函数 "; } private: // int c; protected: }; void objplay(Father *base) { base->print(); } int main() { //Child c1(3); //objplay(&c1); Father *pP = NULL; Child *pC = NULL; Child array[] = {Child(1), Child(2), Child(3)};//这里还必须三个了。 pP = array; pC = array; pP->print();//这里发生多态 pC->print(); //多态发生吗,不不不,不发生,这里只是调用子类的函数 pP++; pC++; pP->print(); pC->print(); //多态发生 pP++; pC++; pP->print(); pC->print(); //多态发生 system("pause"); return 0; }
子类对象可以当作父类对象使用
子类对象可以直接赋值给父类对象
子类对象可以直接初始化父类对象
父类指针可以直接指向子类对象(这里仅仅指的是子类继承的父类的对象)
父类引用可以直接引用子类对象(这里仅仅指的是子类继承的父类的对象)
而子类的指针和应用就不可以指向父类对象
子类可以用父类的所有东西,只是对错而已,而父类不能用子类的任何东西。
所以上面两句和线面这一句并不矛盾。
曾经写的这句,现在不理解这句了?
多态的必备条件之一是必须是父类的指针或者引用,
而子类的指针和引用只会调用子类的函数,不会调用父类的,子类的指针和应用就不可以指向父类对象,
而其他的形式,比如:子类对象. XXX 这里就可以用父类的所有东西,而父类对象.XXX 就只能用自己的父类的成员。
所以综上所述,指针、引用和那个.是不一样的情况呢
是的,指针引用和直接对象.是不同的
调用函数的形参是父类的指针和引用可以指向子类的任何成员,但是调用函数的形参子类的指针和引用就只能指向自己的成员,不可以指向父类的。
子类对象成员调用 这里就可以用父类的所有东西,而父类对象的成员调用 就只能用自己的父类的成员
注意!!类定义的指针使用的时候,必须分配内存!!!
#include<iostream> using namespace std; class Father { public: Father() { cout << "i am father "; } virtual void print() { cout << " 我是父类的:"; cout << this->f << endl; } public: int f; }; class Child :public Father { public: Child() { cout << "i am child "; } virtual void print() { cout << " 我是子类的: "; cout << this->f << endl; cout << this->c << endl; } public: int c; }; void objplay(Father *tem1) { cout << "形参为 Father *tem1 的 tem1->f==========>"; cout << tem1->f << endl; } void objplay2(Child *tem2) { cout << "形参为 Child *tem2 的 tem2->c==========>"; cout << tem2->c << endl; cout << "形参为 Child *tem2 的 tem2->f==========>"; cout << tem2->f << endl; } int main() { Child c1; Father f1; c1.c = 5; c1.f = 6; cout << "c1.print()=====> "; c1.print();//调用子类的 输出为6 f1.f = 7; cout << "f1.print()=====> "; f1.print();//调用父类的 输出为7 //Child *c2; 这样子写就会出错,因为指针使用的时候必须必须分配内存空间 Child *c2 = new Child;//一旦用类名字定义函数就会调用析构函数。 //Father *f2; Father *f2 = new Father; c2->c = 8; c2->f = 9; cout << "c2.print()=====> "; c2->print();//调用子类的 f2->f = 10; cout << "f2.print()=====> "; f2->print();//调用父类的 objplay(&c1);// 这里虽然是父类的指针,但是指向的是子类的对象地址。所以调用显示的是子类的 objplay(&f1);//父类 objplay(c2);//这里居然也是调用的子类的值 objplay(f2);//父类 objplay2(&c1); //objplay2(&f1); 出错 objplay2(c2); //objplay2(f2); 出错 system("pause"); }
这个的例子就表明的很明显了。