C&C++快速入门

19、类和封装

1、课程目标

  • 理解面向对象编程的基本概念
  • 掌握类的定义和实例化
  • 理解访问控制(public/private/protected)
  • 掌握构造函数和析构函数

2、名词解释

术语 说明
类(class) 对象的模板/蓝图
对象 类的实例
封装 隐藏内部实现,只暴露接口
成员变量 类中的数据
成员函数 类中的方法
构造函数 创建对象时自动调用
析构函数 销毁对象时自动调用
this 指向当前对象的指针

3、代码实现

1. 类的基本定义

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

class Person {
private:  // 私有成员
    char m_name[32];
    int m_age;

public:   // 公有成员
    // 构造函数
    Person() {
        strcpy(m_name, "Unknown");
        m_age = 0;
        cout << "默认构造函数" << endl;
    }
    
    Person(const char* name, int age) {
        strcpy(m_name, name);
        m_age = age;
        cout << "参数构造函数: " << m_name << endl;
    }
    
    // 析构函数
    ~Person() {
        cout << "析构函数: " << m_name << endl;
    }
    
    // 成员函数
    void SetName(const char* name) {
        strcpy(m_name, name);
    }
    
    const char* GetName() const {
        return m_name;
    }
    
    void SetAge(int age) {
        if (age >= 0 && age < 150) {
            m_age = age;
        }
    }
    
    int GetAge() const {
        return m_age;
    }
    
    void Print() const {
        cout << "Name: " << m_name << ", Age: " << m_age << endl;
    }
};

int main() {
    cout << "=== 类和封装 ===" << endl << endl;
    
    // 创建对象
    Person p1;                    // 调用默认构造
    Person p2("Alice", 25);      // 调用参数构造
    
    cout << endl;
    p1.Print();
    p2.Print();
    
    // 使用setter修改
    p1.SetName("Bob");
    p1.SetAge(30);
    cout << "\n修改后:" << endl;
    p1.Print();
    
    cout << endl;
    return 0;  // 这里会调用析构函数
}

2. 动态分配对象

#include <iostream>
using namespace std;

class Buffer {
private:
    char* m_data;
    int m_size;
    
public:
    Buffer(int size) {
        m_size = size;
        m_data = new char[size];
        memset(m_data, 0, size);
        cout << "Buffer分配: " << size << "字节" << endl;
    }
    
    ~Buffer() {
        delete[] m_data;
        cout << "Buffer释放" << endl;
    }
    
    char* GetData() { return m_data; }
    int GetSize() { return m_size; }
};

int main() {
    cout << "=== 动态分配 ===" << endl << endl;
    
    // 在堆上创建
    Buffer* pBuf = new Buffer(1024);
    
    strcpy(pBuf->GetData(), "Hello Buffer!");
    cout << "内容: " << pBuf->GetData() << endl;
    
    delete pBuf;  // 手动释放
    
    cout << "\n程序结束" << endl;
    return 0;
}

3. 安全编程中的类设计

#include <iostream>
#include <windows.h>
using namespace std;

class HandleWrapper {
private:
    HANDLE m_handle;
    
public:
    HandleWrapper() : m_handle(INVALID_HANDLE_VALUE) {}
    
    HandleWrapper(HANDLE h) : m_handle(h) {}
    
    ~HandleWrapper() {
        Close();
    }
    
    void Close() {
        if (m_handle != INVALID_HANDLE_VALUE && m_handle != NULL) {
            CloseHandle(m_handle);
            m_handle = INVALID_HANDLE_VALUE;
        }
    }
    
    HANDLE Get() const { return m_handle; }
    bool IsValid() const { 
        return m_handle != INVALID_HANDLE_VALUE && m_handle != NULL; 
    }
    
    // 禁止拷贝
    HandleWrapper(const HandleWrapper&) = delete;
    HandleWrapper& operator=(const HandleWrapper&) = delete;
};

int main() {
    cout << "=== 句柄包装类 ===" << endl << endl;
    
    {
        HandleWrapper file(
            CreateFileA("test.txt", GENERIC_WRITE, 0, NULL,
                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
        
        if (file.IsValid()) {
            cout << "文件创建成功" << endl;
            const char* data = "Hello";
            DWORD written;
            WriteFile(file.Get(), data, 5, &written, NULL);
        }
    }  // 自动关闭句柄
    
    cout << "句柄已自动释放" << endl;
    return 0;
}

4、课后作业

4.1、作业1:实现银行账户类

实现存款、取款、查询余额功能。

4.2、作业2:实现内存包装类

封装VirtualAlloc/VirtualFree,自动释放内存。