9. 对象指针与对象数组

2023-05-16

一、对象指针

  • 声明形式:

    类名 *对象指针名;

    Clock c(8, 3, 10);
    Clock *ptr;
    ptr = &c;
    
    image-20230510150019734
  • 通过指针访问对象成员(一般类的属性都是封装起来的,因此通常是通过指针访问成员函数)

    对象指针名->成员名

    ptr->getHour();相当于(*ptr).getHour();

// Clock类的定义与之前的一致

int main(){
    Clock c(8, 3, 10);					// 定义并初始化对象c
    Clock *ptr = &c;					// 定义对象指针,用c的地址将其初始化
    cout << ptr->getHour() << endl;		 // 利用指针访问对象成员
    cout << c.getHour() << endl;		 // 利用对象名访问对象成员
    return 0;
}

二、this指针

  1. 问题:

    • C++中成员函数和成员变量是分开存储的
    • 每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码
      • 例如一个Point点类,包含一个getX函数来获取该点横坐标,如果有多个Point类的对象,并且同时执行getX函数,那么系统就必须要区分每次执行调用该函数的语句时被赋值的数据成员是属于哪一个对象的
      • 这一块代码要如何区分是哪个对象调用自己???
  2. 解决方法:this指针

    • this指针指向被调用的成员函数所属的对象
      • this指针是隐含于每一个类的非静态成员函数中的特殊指针
  • 明确地指出了成员函数当前所操作地数据所属地对象

     - 当通过一个对象调用成员函数时,**系统先将该对象的地址赋给this指针**,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针
    
     例如:Clock类的getHour函数中的语句`return hour`,相当于:`return this->hour`
    
     例如:Clock类的display函数中的语句
    
     ```c++
     void display() {
             cout << hour << ":" << minute << ":" << second << endl;
     }
     
     // 相当于:
     cout << this->hour << ":" << this->minute << ":" << this->second << endl;
     ```
    
    • this指针的用途:
      • 当形参和成员变量同名时,可用this指针来区分(使用this指针就便于不用再另起其他的变量名进行区分)

        image-20230510151412794
      • 在类的非静态成员函数中返回对象本身,可使用return *this

三、动态创建对象

  • new 类型名T(初始化参数列表)
    • 功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值
    • 结果值:
      • 成功:T类型的指针,指向新分配的内存
      • 失败:抛出异常
  • delete 指针p
    • 功能:释放指针p所指向的内存。p必须是new操作的返回值

例子:

#include <iostream>
using namespace std;

class Point {
private:
    int x, y;
public:
    Point() : x(0), y(0) {
        cout << "Default Constructor called." << endl;
    }
    Point(int x, int y) : x(x), y(y) {
        cout << "Constructor called." << endl;
    }
    ~Point() { cout << "Destructor called." << endl; }
    
    int getX() { return x; }
    int getY() { return y; }
    void move(int newX, int newY) {
        x = newX;
        y = newY;
    } 
};

int main() {
    cout << "Step one: " << endl;
    Point *ptr1 = new Point;		 
    // ptr1定义为Point类指针
    // new Point会调用构造函数创建一个Point对象,没有括号所以是缺省构造函数,然后将该对象的首地址赋给ptr1指针
    // ptr1就指向了这个新创建的Point对象,从而建立了二者之间的联系
    
    delete ptr1;					// 删除对象,自动调用析构函数
    
    cout << "Step two: " << endl;
    ptr1 = new Point(1, 2); // new Point(1, 2)调用有参构造函数
    delete ptr1;
    
    return 0;
}
image-20230510153457429

四、申请和释放动态数组

  • 分配new 类型名T[数组长度]
    • 数组长度可以是任何表达式,在运行时计算
  • 释放delete[] 数组名p
    • 释放指针p所指向的数组
    • p必须是用new分配得到的数组首地址

例子:

image-20230510154628958
#include <iostream>
using namespace std;

class Point { 同上 }

int main() {
    
    Point *ptr = new Point[2]; 			// 创建对象数组
    
    ptr[0].move(5, 10);				   // 通过指针访问数组元素的成员
    ptr[1].move(15, 20);			   // 通过指针访问数组元素的成员
    cout << "Deleting..." << endl;
    
    delete[] ptr;					  // 删除整个对象数组
    
    return 0;
}

/**********************/
Point ptr[2]; 

// 与Point *ptr = new Point[2]; 效果相同
// 区别:使用静态数组方式,数组长度是固定的,系统自动分配和释放内存
//		采用new则可以任意设置数组长度
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

9. 对象指针与对象数组 的相关文章

随机推荐