Ⅰ 类与对象③

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); }   //写个函数,在函数里访问就可以啦

猜你喜欢

转载自www.cnblogs.com/syzyaa/p/12695786.html