• Ⅰ 类与对象③


    3.复杂对象的使用与this指针

    3.1 动态对象与对象指针

     3.1.1 对象指针

    ◼对象指针指向对象存放的地址

    ◼ 定义与使用

    类名 *对象指针名;

    对象指针名->数据成员;

    对象指针名->数据函数;

    ◼ 优点:地址传递,效率高

    3.1.2 动态对象

    CCircle *g_pc = NULL;  //定义了一个对象指针
    
    void display()
    {
        g_pc->Draw();  //使用对象指针,CCirle里面的Draw函数
    }
    
    void keyboard(unsigned char key)
    {
        switch (key)
        {
        case '1':
            if (g_pc!=NULL)  //指针的使用
                delete g_pc;                               //杯子里倒水,换杯子
            g_pc = new CCircle(400, 300, 100, PURPLE);  //动态对象
            break;                                            //就是新建和释放空间
        case '2':
            if (g_pc!=NULL)
                delete g_pc;
            g_pc = new CCircle(500, 200, 150, RED);
            break;
        }
    }
    CCircle *g_c=NULL; 
    int g_n = 0; 
    void LoadCircles(const char *fileName) 
    { 
        FILE *fp = NULL; 
        float x, y, r; 
        int clr;
    
        fp = fopen(fileName, "r");   //打开并读取文件,因为有很多的数
        fscanf(fp, "%d", &g_n); 
        cout <<g_n <<endl; 
        
        g_c = new CCircle[g_n];   //连续的数列,g_c指向首地址
        
        for(int i=0; i<g_n; i++) 
        { 
            fscanf(fp, "%f %f %f %d", &x, &y, &r, &clr); 
            g_c[i].Set(x, y, r, clr); 
        }
        fclose(fp);
    }
        delete []g_c;  //new时有【】,delete时也有

    3.2 对象引用

    3.3 对象数组

    ◼ 与对象为元素的数组

    ◼ 定义与初始化

    类名 对象数组名[n];

    初始化:

    数组名[n] = { 类名(初始值1,初始值2,..),

            类名(初始值1,初始值2,..),

          … 类名(初始值1,初始值2,..) } ;

    CCircle g_cir[2] = {CCircle(300,200,100,RED),CCircle(200,280,30,BLUE)};  
      int     a[2]   = {         1       ,           2            };
    void display()
    {
      //  g_pc->Draw();
        for(int i=0;i<2;i++)
            g_cir[i].Draw();
    }

    3.4 this指针

    ◼ 一个系统预定义的指针,指向当前对象(即当前对象的地址)

     

    this指针:哪里需要哪里搬,就是指向结构体首地址的,v0和v1用的是同一个成员函数

     v1和v0都有自己各自的地址,x和y虽然名字一样但所在的地址也不一样,一样的是this指针只有一个,所以是到处指的。

     *this:返回当前的对象

    3.5 组合对象

    3.5.1 定义

    就是在一个类1(组合类)中,调用了别的类2(成员类):类2  p(组合对象)

    class CPoint   //传说中的成员类
    {
        float x;
        float y;
    public:
        CPoint(float _x=0, float _y=0)  //初始化
        {
            x = _x;
            y = _y;
        }
        float GetX() {return x;} 
        float GetY() {return y;} 
        void SetX(float _x) {x=_x;} 
        void SetY(float _y) {y=_y;} 
        void Move(float dx, float dy) { x+=dx; y+=dy; }
    };
    
    class CCircle
    {
        CPoint p;    //来啦来啦!组合对象!
        unsigned long clr;
        float r;
    public:
        CCircle(float x, float y, int _r, unsigned long _clr=0x00FF00):p(x, y)
        {
            r = _r;       //p.x=x;p.y=y;❌为私有的,能不能直接操作,若改为公有的
            clr = _clr;  //在使用p的时候,会自动调用带默认参数的构造函数,所以多了几步,
            cout << "Circle con1" << endl;
        }
        CCircle(CPoint _p, int _r):p(_p)
        {
            r = _r;
            cout << "Circle con2" << endl;
        }
        double GetArea(); 
        double GetPerimeter(); 
        void Move(float dx, float dy); 
        void Set(float x, float y); 
        void Scale(float s); 
    };
    //代码重用:不仅是圆类,三角形类、巨星类都可以用,Move函数只有一个版本。只用写一次
    void CCircle::Move(float dx, float dy)
    {
        p.Move(dx, dy);
    }

    ■ 成员对象按照在其组合类的声明中出现的次序,依次调用各自的构造函数, 而不是按初始化列表中的顺序

    void Set(float x, float y) { p.x = x; p.y = y; }  //不可以访问,私有的
    void Set(float x, float y) { p.SetX(x); p.SetY(y); }   //写个函数,在函数里访问就可以啦
    
  • 相关阅读:
    Codeforces 672D
    Codeforces 672C
    Codeforces 673D
    Codeforces 1181D
    Codeforces 1181C
    Codeforces 1011F
    Codeforces 1011E
    2020.1.3计导全面复习
    csp模拟题-201903
    CCF模拟题-201909
  • 原文地址:https://www.cnblogs.com/syzyaa/p/12695786.html
Copyright © 2020-2023  润新知