C++ 类与对象的基本概念和使用

发布于:2025-06-11 ⋅ 阅读:(31) ⋅ 点赞:(0)


前言

C++ 是一种面向对象的编程语言,类和对象是其核心特性之一。类是一种用户自定义的数据类型,用于封装数据和对数据的操作。对象是类的实例,具有类定义的属性和行为。


一、基本概念

1. 类(Class)

  • 定义:类是用户自定义的数据类型,是创建对象的蓝图或模板

  • 组成

    • 数据成员(属性/特征)

    • 成员函数(方法/行为)

    • 访问修饰符(控制访问权限)

2. 对象(Object)

  • 定义:对象是类的实例,占用实际内存空间

  • 特点:每个对象都有自己的数据成员副本,但共享成员函数

二、类的定义与使用

1. 基本语法

class ClassName {
    // 访问修饰符
private:
    // 私有成员(只能在类内部访问)
    
protected:
    // 受保护成员(类内部和派生类可访问)
    
public:
    // 公共成员(任何地方都可访问)
    
    // 构造函数
    ClassName();
    
    // 成员函数
    returnType functionName(parameters);
    
    // 析构函数
    ~ClassName();
};

2. 访问修饰符

修饰符 访问权限
private 仅类内部可访问(默认)
protected 类内部和派生类可访问
public 任何地方都可访问

三、对象的创建与使用

1. 创建对象

// 方式1:栈上分配
ClassName obj1;            // 调用默认构造函数
ClassName obj2(params);    // 调用带参构造函数

// 方式2:堆上分配
ClassName* ptr = new ClassName();    // 动态分配
delete ptr;                         // 必须手动释放

2. 访问成员

obj.memberVariable;     // 访问数据成员
obj.memberFunction();   // 调用成员函数

ptr->memberVariable;    // 指针访问数据成员
ptr->memberFunction();  // 指针调用成员函数

四、构造函数与析构函数

1. 构造函数

class Person {
private:
    string name;
    int age;
    
public:
    // 默认构造函数
    Person() : name("Unknown"), age(0) {}
    
    // 参数化构造函数
    Person(string n, int a) : name(n), age(a) {}
    
};

2. 析构函数

class ResourceHolder {
private:
    int* data;
    
public:
    ResourceHolder(int size) {
        data = new int[size];
    }
    
    ~ResourceHolder() {
        delete[] data;  // 释放资源
        cout << "资源已释放" << endl;
    }
};

五、this指针

  • 作用:指向当前对象的指针

  • 用途

    • 区分成员变量和局部变量

    • 返回对象自身引用

    • 在成员函数中访问当前对象

class Example {
private:
    int value;
    
public:
    void setValue(int value) {
        this->value = value;  // 使用this区分同名变量
    }
    
    Example& getThis() {
        return *this;  // 返回当前对象的引用
    }
};

六、静态成员

1. 静态数据成员

class Counter {
private:
    static int count;  // 声明
    
public:
    Counter() { count++; }
    ~Counter() { count--; }
    
    static int getCount() { return count; }
};

int Counter::count = 0;  // 定义并初始化

要注意的是这里初始化要在类外初始化

2. 静态成员函数

class MathUtils {
public:
    static double square(double x) {
        return x * x;
    }
};

// 调用方式
double result = MathUtils::square(5.0);

如果要在类外写的话要加上作用域在调用时应注意变量类型

七、常成员与常对象

1. 常成员函数

class BankAccount {
private:
    double balance;
    
public:
    double getBalance() const {  // 不会修改对象状态
        return balance;
    }
};

2. 常对象

const BankAccount acc;  // 常对象
double b = acc.getBalance();  // 只能调用常成员函数

这里注意常对象只能调用常成员函数

类的应用

#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    string name;
    int id;
    double gpa;
    
public:
    // 构造函数
    Student(string n, int i, double g) : name(n), id(i), gpa(g) {}
    
    // 成员函数
    void display() const {
        cout << "学生姓名: " << name << endl;
        cout << "学号: " << id << endl;
        cout << "GPA: " << gpa << endl;
    }
    
    void study(int hours) {
        gpa += hours * 0.1;
        if (gpa > 4.0) gpa = 4.0;
    }
    
    // Getter/Setter
    string getName() const { return name; }
    void setName(string n) { name = n; }
    
    double getGPA() const { return gpa; }
};

int main() {
    // 创建对象
    Student stu1("张三", 1001, 3.5);
    Student stu2("李四", 1002, 3.2);
    
    // 使用对象
    stu1.display();
    stu2.study(5);
    
    cout << stu2.getName() << "的新GPA: " << stu2.getGPA() << endl;
    
    return 0;
}
  1. 类定义部分:定义了一个名为Student的类,包含三个私有数据成员(nameidgpa)和多个公有成员函数。这种将数据私有、方法公有的设计体现了面向对象编程的封装特性。

  2. 构造函数:采用初始化列表语法:name(n), id(i), gpa(g)来初始化成员变量,这种方式比在构造函数体内赋值更高效,特别是对于类类型成员。

  3. 成员函数:包含了显示信息的display()方法、模拟学习的study()方法以及获取/设置属性的方法。const修饰的方法承诺不会修改对象状态。

使用注意事项

  1. 初始化列表:在构造函数中,应优先使用初始化列表而非构造函数体内赋值,特别是对于const成员、引用成员和类类型成员。

  2. const方法:不修改对象状态的成员函数都应声明为const,这样const对象也能调用这些方法,提高代码的灵活性。

  3. 封装程度:应根据实际需求合理设计getter/setter,不是所有私有成员都需要提供公开访问接口,特别是像GPA这样需要受控修改的数据。

  4. 参数传递:对于字符串等可能较大的参数,应考虑使用const引用传递(如setName(const string& n)),避免不必要的拷贝。


总结

使用类时需要掌握几个关键点:构造函数用于初始化对象,析构函数用于清理资源;this指针指向当前对象,用于解决命名冲突;静态成员属于类而非对象,被所有对象共享;const成员函数保证不修改对象状态。类设计应遵循封装原则,将数据设为private,通过public方法提供访问接口,必要时使用protected为派生类保留访问权限。