• 这里面盲点很多,构造函数的调用问题,还有vptr指针的++问题(已解决)


    #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");
    }
    

      

      

    这个的例子就表明的很明显了。

  • 相关阅读:
    Linux文件/proc/net/tcp分析
    为什么系统调用会消耗较多资源
    为什么Linux默认页大小是4KB
    为什么Linux需要虚拟内存
    Make 命令教程
    关于同步的一点思考-下
    关于同步的一点思考-上
    Linux下的进程控制块(PCB)
    汇编语言基础:寄存器和系统调用
    内核栈与thread_info结构详解
  • 原文地址:https://www.cnblogs.com/xiaochige/p/6618415.html
Copyright © 2020-2023  润新知