C++ 中,指向类对象的指针是指一个指针变量,它指向类的一个实例。通过这个指针,可以访问对象的成员(包括属性和方法)。可以通过指针动态地操作对象,适用于动态内存管理和对象之间的引用传递等场景。本文主要介绍C++中指向类对象的指针。

1、C++ 指向对象的指针

创建对像时,编译系统会为每一个对像分配一定的存储空间,以存放其成员,对象空间的起始地址就是

对象的指针。可以定义一个指针变量,用来存和对象的指针。使用 -> 操作符访问类对象的成员(相当于通过指针访问对象)。也可以使用 * 解引用指针后再用 . 操作符访问成员。

例如,

#include <iostream>
using namespace std;
class Area
{
   public:
      // 构造函数定义
      Area(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
      }
      double Volume()
      {
         return length * breadth * height;
      }
   private:
      double length;     // Length of a Area
      double breadth;    // Breadth of a Area
      double height;     // Height of a Area
};
int main(void)
{
   Area Area1(3.3, 1.2, 1.5);    // Declare Area1
   Area Area2(8.5, 6.0, 2.0);    // Declare Area2
   Area *ptrArea;                // Declare pointer to a class.
   // 保存第一个对象的地址
   ptrArea = &Area1;
   // 现在尝试使用成员访问运算符来访问成员
   cout << "Volume of Area1: " << ptrArea->Volume() << endl;
   // 保存第二个对象的地址
   ptrArea = &Area2;
   // 现在尝试使用成员访问运算符来访问成员
   cout << "Volume of Area2: " << ptrArea->Volume() << endl;
  
   return 0;
}

2、使用场景

指向类对象的指针在C++中应用广泛,尤其是在需要动态内存管理、多态性、抽象类、对象数组、工厂模式等情况下。它提供了灵活且高效的方式来操作和管理对象的生命周期。

1)动态内存分配

当需要在运行时动态创建对象时,使用指向类对象的指针非常有用,特别是在使用 new 运算符时。

#include <iostream>
using namespace std;

class MyClass {
public:
    int x;

    // 构造函数,初始化x
    MyClass(int val) : x(val) {
        cout << "MyClass object created with value " << x << endl;
    }
    // 成员函数,显示x的值
    void display() {
        cout << "Value of x: " << x << endl;
    }
    // 析构函数,释放资源
    ~MyClass() {
        cout << "MyClass object with value " 
        << x << " is destroyed." << endl;
    }
};

int main() {
    // 动态创建对象
    // 使用new运算符动态分配内存并调用构造函数
    MyClass* ptr = new MyClass(20);  
    // 通过指针调用display函数
    ptr->display();             

    // 释放动态分配的内存
    // 使用delete运算符释放内存并调用析构函数
    delete ptr;                      

    return 0;
}

2)类对象的多态性

在面向对象编程中,通过指向基类的指针,可以实现多态,使得在运行时决定调用哪种方法(函数重载)。

#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() {
        cout << "Base class" << endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        cout << "Derived class" << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    ptr->show();  // 调用 Derived 类的 show()
    delete ptr;
}

3)接口与抽象类的使用

在设计接口或抽象类时,指向类对象的指针非常常见。通过抽象类指针来操作派生类对象。

#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() = 0;  // 纯虚函数
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing Circle" << endl;
    }
};

int main() {
    // 指向派生类的指针
    Shape* shapePtr = new Circle();  
    // 调用派生类的 draw()
    shapePtr->draw();                
    delete shapePtr;
}

推荐文档