2017C++基础——网课笔记【下】(5到9)

五. vptr指针的分布初始化

vptr指针是分布初始化的

#include <iostream>

using namespace std;

class Parent
{
public:
    Parent(int a)
    {
        cout<<"Parent(int)...."<<endl;
        this->a = a;

        //print();//问题:是调用父类的print()还是儿子的print()
                //答案:通过结果,此时调用的父类的print,并不是子类的print
    }

    virtual void print()
    {
        cout<<"Parent::print()...a"<<endl;
    }
private:
    int a;
};

class Child: public Parent
{
public:
    Child(int a,int b): Parent(a) // 在调用父类的构造器的时候,会将vptr指针当做父类来处理
                                  // 此时会临时指向父亲的虚函数表
    {
        //将子类对象的空间由编程子类对象处理,vptr指针,就从指向父类的表,变成指向子类的表

        cout<<"Child(int,int)..."<<endl;
        print(); //此时vptr指针已经回到了子类的表,调用的是子类的print函数
        this->b = b;
    }

    virtual void print()
    {
        cout<<"Child::print()...b"<<endl;
    }
private:
    int b;
};

int main()
{
    Parent * pp = new Child(10,20);
    //pp->print();

    delete pp;
    return 0;
}

六. 父类指针和子类指针的步长


#include <iostream>

using namespace std;

class Parent
{
public:
    Parent(int a)
    {
        this->a = a;
    }

    virtual void print()
    {
        cout<<"Parent::print...a = "<< a <<endl;
    }

    int a;
};

class Child: public Parent
{
public:
    Child(int a): Parent(a)
    {

    }

    virtual void print()
    {
        cout<<"Child::print...a = "<< a <<endl;
    }
    int b;
};

int main()
{
    Child array[] = {Child(0),Child(1),Child(2)};

    Parent *pp = &array[0];
    Child *cp = &array[0];

    pp->print();
    cp->print();

    pp++; //pp+sizeof(Parent)
    cp++;  //cp+sizeof(Child)



    cout<<"----------------"<<endl;

    int i = 0;
    for(pp = &array[0], i =0;i<3;i++,pp++) //这里会出问题,因为父类指针的步长,与子类对象不同。
                                            //而指针的++是按照父类指针去进行的
    {
        pp->print();
    }


    return 0;
}

       七.纯虚函数和抽象类1


#include <iostream>

using namespace std;

//图形类
//如果说一个类,拥有一个纯虚函数
//则称这个类是一个抽象类
//不管这个类中,有没有成员属性
//只要这个类有纯虚函数,就是抽象类。抽象类就是不能实例化的
class Shape
{
public:
    //求图形面积的方法
    //表示图形类声明一个方法getArea(),它是一个纯虚函数,没有函数的实现
    virtual double getArea() = 0;
    //virtual void print() = 0;

};

//正方形
//如果一个普通类,继承拥有纯虚函数的类,必须要重写这个纯虚函数
//如果说不去重写纯虚函数,则依然是抽象类,则依然不能被实例化
class Rect: public Shape
{
public:
    Rect(int a)
    {
        this->a = a;
    }
    virtual double getArea()
    {
        return this->a * this->a;
    }
private:
    int a;
};

class Circle: public Shape
{
public:
    Circle(int r)
    {
        this->r = r;
    }

    virtual double getArea()
    {
        return 3.14 * r * r;
    }

private:
    int r;
};

class Triangle: public Shape
{
public:
    Triangle(int b,int h)
    {
        this->b = b;
        this->h = h;
    }

    virtual double getArea()
    {
        return 0.5 * b * h;
    }
private:
    int b;
    int h;
};

int main()
{
    //main中所有使用的变量类型,都是抽象类Shape的类型
    Shape *rp = new Rect(10);

    cout<<"Rectangle is:"<<rp->getArea()<<endl;

    Shape *cp = new Circle(10);

    cout<<"Circle is:"<<cp->getArea()<<endl;

    Shape *tp = new Triangle(10,6);

    cout<<"Triangle is:"<<tp->getArea()<<endl;

    return 0;
}

 八.纯虚函数和抽象类2



 九.中午回顾(略)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值