当前位置: 首页 > news >正文

C++ 入门四:类与对象 —— 面向对象编程的核心基石

一、类的定义

1. 类的基本形式

class 类名 {
public:       // 公有成员(类内外均可访问)
    数据类型 数据成员;       // 公有数据成员
    数据类型 成员函数(参数列表);  // 公有成员函数声明
protected:    // 保护成员(类内和派生类可访问)
    数据类型 保护数据成员;
    数据类型 保护成员函数(参数列表);
private:     // 私有成员(仅类内可访问)
    数据类型 私有数据成员;
    数据类型 成员函数(参数列表);  // 私有成员函数声明
};  // 类定义结束必须加分号

2. 详细说明

  • 成员分类:类包含两种成员:
    • 数据成员:描述类的属性,如学生类中的姓名年龄
    • 成员函数:描述类的行为,如学生类中的设置年龄获取成绩
  • 访问权限
    • public(公有):成员可在类外直接访问,例如对象名.公有成员
    • protected(保护):成员可在类内和派生类中访问,类外不可直接访问。
    • private(私有):仅类内成员函数或友元可访问,类外和派生类(除非友元)不可直接访问。
  • 成员函数定义
    • 类内定义:直接在类体中编写函数体,自动成为内联函数(隐式inline)。
    • 类外定义:使用类名::作用域限定符,例如:
      void 类名::成员函数(参数列表) { /* 函数体 */ }
      

3. 示例:定义学生类

class Student {
public:
    // 公有数据成员
    char name[20];  // 姓名
    int age;        // 年龄

    // 公有成员函数(类内定义)
    void set_score(float s) {  // 设置成绩(私有成员)
        score = s;
    }

    // 公有成员函数(类外定义)
    float get_score();  // 获取成绩声明

protected:
    int grade;  // 年级(保护成员,派生类可访问)

private:
    float score;  // 成绩(私有成员,仅类内访问)
};

// 类外定义成员函数
float Student::get_score() {
    return score;  // 访问私有成员score
}

二、对象的定义与成员访问

1. 对象定义

  • 语法类名 对象名; 或 类名 对象名(参数列表);(调用带参构造函数)
  • 示例
    Student stu1;         // 定义对象stu1(调用默认构造函数)
    Student stu2("张三", 18);  // 假设存在带参构造函数
    

2. 成员访问

  • 公有成员:直接通过对象名.成员名访问。
    stu1.age = 18;       // 合法,age是公有成员
    strcpy(stu1.name, "李四"); // 合法
    
  • 私有 / 保护成员:通过公有成员函数间接访问。
    stu1.set_score(90.5); // 合法,调用公有函数设置私有成员score
    // stu1.score = 90.5;  // 非法,score是私有成员
    

三、构造函数:对象的初始化

在面向对象编程中,对象的初始化是一个关键环节。构造函数作为类的特殊成员函数,承担着初始化对象的重要职责。下面将从基础概念到高级用法逐步解析构造函数的核心知识。

1. 构造函数概述

语法规则
  • 函数名:必须与类名完全相同(包括大小写)。
  • 返回值:没有返回值(不能写void)。
  • 调用时机:创建对象时自动调用(栈上定义、堆上new操作、函数返回对象等场景)。
核心作用
  • 成员初始化:为对象的成员变量赋初始值(如数值类型设为默认值、指针指向有效内存)。
  • 资源分配:为对象分配运行所需资源(如动态内存、文件句柄、网络连接等)。
示例:基础构造函数
class Book {
public:
    // 构造函数:初始化书名和页数
    Book() {
        strcpy(title, "未命名");  // 初始化C风格字符串
        pages = 0;
    }
private:
    char title[50];
    int pages;
};

int main() {
    Book novel;  // 创建对象时自动调用Book()构造函数
    return 0;
}

2. 构造函数分类

(1)无参构造函数(默认构造函数)
定义与特性
  • 无参数:函数括号内没有参数列表。
  • 编译器自动生成:若类中未定义任何构造函数,编译器会生成一个空的默认构造函数(成员变量初始化为默认值,如数值为 0、指针为nullptr)。
  • 手动定义的必要性:若定义了其他带参构造函数,编译器不再自动生成默认构造函数,需手动定义以支持无参创建对象。
示例:手动定义默认构造函数
class Student {
public:
    // 显式定义默认构造函数
    Student() {
        id = 0;
        name = "匿名";
        score = 0.0f;
    }
private:
    int id;
    std::string name;
    float score;
};

Student stu;  // 调用默认构造函数,id=0,name="匿名",score=0.0f
(2)带参构造函数
定义与作用
  • 包含参数:通过参数为成员变量赋初始值,支持灵活初始化。
  • 参数作用域:参数名可与成员变量同名,通过this指针区分(this->成员变量)。
示例:通过参数初始化成员
class Circle {
public:
    // 带参构造函数:初始化半径和面积
    Circle(float r) {
        radius = r;  // 成员变量radius = 参数r
        area = 3.14f * r * r;  // 计算初始面积
    }
private:
    float radius;
    float area;
};

Circle c(5.0f);  // 创建半径5.0的圆,area自动计算为78.5
(3)初始化列表(Constructor Initializer List)
语法与格式
  • 位置:在构造函数参数列表后,使用:分隔,多个成员用逗号分隔。
  • 格式构造函数(参数列表) : 成员1(值1), 成员2(值2), ... { 函数体 }
核心优势
  • 效率更高:直接调用成员的构造函数(如类成员对象),避免先默认构造再赋值。
  • 必需场景:初始化const成员或引用成员(二者必须在定义时初始化)。
示例:初始化列表的使用
class Person {
public:
    // 普通成员与const成员的初始化
    Person(std::string n, int a) : name(n), age(a) { 
        // 函数体可空,初始化在列表完成
    }
    // 引用成员必须通过初始化列表赋值
    Person(std::string n, int a, int& ref) : name(n), age(a), ref_num(ref) { }
private:
    std::string name;
    int age;
    const int ref_num;  // const引用成员,必须在初始化列表赋值
};

// 初始化const成员的错误与正确写法对比
class ErrorDemo {
    const int value;
public:
    ErrorDemo() { value = 10; }  // 错误!const成员不能赋值
};

class CorrectDemo {
    const int value;
public:
    CorrectDemo() : value(10) { }  // 正确!通过初始化列表赋值
};
(4)构造函数重载
重载规则
  • 函数名相同,但参数列表不同(参数个数、类型、顺序至少有一个不同)。
  • 返回值类型无关:不能通过返回值区分重载构造函数。
示例:多种初始化方式
class Vector {
public:
    // 无参构造:初始化零向量
    Vector() : x(0), y(0) {}
    
    // 单参数构造:二维向量(x=y)
    Vector(float val) : x(val), y(val) {}
    
    // 双参数构造:指定x和y
    Vector(float x_val, float y_val) : x(x_val), y(y_val) {}
private:
    float x, y;
};

// 调用不同构造函数
Vector v1;        // 无参构造,(0, 0)
Vector v2(5.0f);  // 单参构造,(5.0, 5.0)
Vector v3(3.0f, 4.0f);  // 双参构造,(3.0, 4.0)
C++14 简化写法:= default
  • 作用:显式让编译器生成默认构造函数,保持代码简洁。
  • 示例
    class Simple {
    public:
        Simple() = default;  // 等价于空的默认构造函数
        Simple(int x) : data(x) {}
    private:
        int data;
    };
    

3. 初始化 const 成员的强制要求

为什么必须用初始化列表?
  • const成员在声明后不能被赋值(只能初始化),而构造函数的函数体执行时,成员变量已完成定义,无法再对const成员赋值。
  • 初始化列表在成员变量定义时直接赋值,满足const的初始化要求。
示例:const 成员的正确初始化
class MathConstants {
public:
    // 初始化const成员PI和引用成员epsilon(引用必须初始化)
    MathConstants(float eps) : PI(3.14159f), epsilon(eps) {}
private:
    const float PI;  // 圆周率,固定值
    float& epsilon;  // 精度引用,必须在初始化列表赋值
};

// 错误示例:试图在函数体中赋值const成员
class ErrorCase {
    const int value;
public:
    ErrorCase(int v) { value = v; }  // 编译错误!const成员不能赋值
};

// 正确示例:通过初始化列表赋值
class CorrectCase {
    const int value;
public:
    CorrectCase(int v) : value(v) {}  // 正确
};

4. 构造函数的最佳实践

(1)统一使用初始化列表
  • 无论是否为const成员,优先在初始化列表中赋值,提升效率(尤其对类成员对象)。
(2)避免冗余初始化
  • 若成员变量无需特殊处理,可依赖编译器默认初始化(如std::string默认构造为空字符串)。
(3)处理动态资源
  • 在构造函数中分配资源(如new内存),并在析构函数中释放(确保资源配对)。
    class DynamicArray {
    public:
        DynamicArray(int size) : data(new int[size]), length(size) {}
        ~DynamicArray() { delete[] data; }  // 析构函数释放内存
    private:
        int* data;
        int length;
    };
    

总结:构造函数核心知识点

特性说明
必需性创建对象时必须调用构造函数,编译器自动生成默认构造函数(无其他构造函数时)。
初始化方式普通成员可在函数体赋值,const成员和引用成员必须通过初始化列表初始化。
重载规则参数列表不同(个数、类型、顺序),支持灵活的对象创建方式。
资源管理构造函数分配资源,析构函数释放资源,确保内存安全。

通过合理设计构造函数,开发者能确保对象在创建时处于有效状态,为后续操作奠定基础。下一节将深入解析析构函数与对象生命周期管理,进一步理解 C++ 对象的完整生命周期。

四、析构函数:对象的清理

在 C++ 中,对象的生命周期管理至关重要。构造函数负责对象的初始化,而析构函数则承担着对象销毁时的清理工作,确保资源正确释放,避免内存泄漏。下面从基础概念到实战应用逐步解析析构函数的核心知识。

1. 析构函数概述

语法规则
  • 函数名:以~符号开头,后跟类名(与构造函数对应),例如~ClassName()
  • 参数与返回值:没有参数,也没有返回值(不能写void)。
  • 调用时机
    • 栈对象离开作用域时(如函数结束)。
    • 堆对象通过delete释放时(如delete p;)。
    • 程序结束时(全局对象和静态对象销毁)。
核心作用
  • 资源释放:释放构造函数或成员函数分配的资源(如动态内存new、文件句柄fopen、网络连接等)。
  • 数据清理:重置成员变量状态,避免无效引用。
与构造函数的关系
  • 配对使用:构造函数分配资源,析构函数释放资源,形成 “资源管理对”(RAII 模式的基础)。
  • 执行顺序:构造函数按 “基类→派生类” 顺序执行,析构函数按 “派生类→基类” 逆序执行(确保派生类资源先释放,基类后释放)。

2. 示例:释放动态内存(核心场景)

需求:管理动态数组的生命周期

当类中包含动态分配的内存(如new创建的数组),必须在析构函数中用delete释放,否则会导致内存泄漏。

代码实现
#include <iostream>
using namespace std;

class DynamicArray {
private:
    int* data;   // 动态数组指针
    int size;    // 数组大小

public:
    // 构造函数:分配内存并初始化
    DynamicArray(int s) : size(s) {
        data = new int[size];  // 分配size个int的内存空间
        for (int i = 0; i < size; i++) {
            data[i] = i;  // 初始化数组元素
        }
        cout << "构造函数:分配内存,地址=" << data << endl;
    }

    // 析构函数:释放动态内存
    ~DynamicArray() {
        delete[] data;  // 释放数组内存(与new[]配对)
        data = nullptr; // 置空指针,避免野指针
        cout << "析构函数:释放内存,地址=" << data << endl;
    }
};

int main() {
    // 栈对象:离开main作用域时自动调用析构函数
    {
        DynamicArray arr(5);  // 构造函数执行,分配内存
    }  // 作用域结束,析构函数自动调用

    // 堆对象:显式调用delete时触发析构函数
    DynamicArray* ptr = new DynamicArray(3);  // 构造函数执行
    delete ptr;  // 手动释放,析构函数调用
    return 0;
}
代码解释
  1. 构造函数

    • 接收参数size,使用new[]分配动态数组内存。
    • 初始化数组元素,输出内存地址以便观察。
  2. 析构函数

    • 使用delete[]释放动态数组(必须与new[]配对,单个对象用delete)。
    • 释放后将指针置为nullptr,防止后续误操作(野指针问题)。
  3. 调用场景

    • 栈对象arr在离开花括号作用域时,自动调用析构函数。
    • 堆对象ptr通过delete显式释放,触发析构函数。

3. 注意事项与进阶知识

(1)默认析构函数:编译器的 “隐形助手”
  • 自动生成条件:若用户未定义析构函数,编译器会生成一个默认析构函数(空函数)。
    class Simple {
        int value;  // 无自定义析构函数,编译器生成~Simple() {}
    };
    
  • 局限性:默认析构函数仅能释放非动态资源(如基本类型、标准库对象),对new分配的内存、文件句柄等无效,需手动定义析构函数。
(2)析构函数与继承:顺序至关重要
  • 基类与派生类的执行顺序

    1. 创建派生类对象时:先执行基类构造函数 → 再执行派生类构造函数。
    2. 销毁派生类对象时:先执行派生类析构函数 → 再执行基类析构函数(与构造顺序相反)。
    class Base {
    public:
        ~Base() { cout << "Base析构" << endl; }
    };
    class Derived : public Base {
    public:
        ~Derived() { cout << "Derived析构" << endl; }
    };
    
    int main() {
        Derived obj;  // 输出:Base构造 → Derived构造(假设存在构造函数)
                      // 销毁时输出:Derived析构 → Base析构
        return 0;
    }
    
(3)析构函数不能重载
  • 原因:析构函数没有参数列表,无法通过参数区分不同版本,因此每个类最多有一个析构函数。
(4)析构函数与异常处理
  • 原则:析构函数中避免抛出异常,否则可能导致程序终止。
  • 处理方式:若必须处理异常,应在析构函数内部捕获并处理,而非抛出。
    ~DynamicArray() {
        try {
            delete[] data;
        } catch (...) {
            // 处理异常或记录日志
        }
    }
    

4. 最佳实践:资源管理的黄金法则

(1)RAII 模式(资源获取即初始化)
  • 核心思想:通过构造函数获取资源,析构函数释放资源,确保资源生命周期与对象绑定。
  • 典型应用
    • 动态内存:new/delete配对。
    • 文件操作:构造函数打开文件,析构函数关闭文件。
    class FileHandler {
    public:
        FileHandler(const char* path) {
            file = fopen(path, "r");  // 构造函数打开文件
        }
        ~FileHandler() {
            if (file) fclose(file);  // 析构函数关闭文件
        }
    private:
        FILE* file;
    };
    
(2)避免手动管理资源:使用智能指针
  • C++11 引入std::unique_ptrstd::shared_ptr,自动管理动态内存,无需手动编写析构函数。
    #include <memory>
    class ModernArray {
    private:
        std::unique_ptr<int[]> data;  // 智能指针自动释放内存
    public:
        ModernArray(int size) : data(new int[size]) {}  // 无需析构函数
    };
    

总结:析构函数核心知识点

特性说明
语法特征~类名命名,无参数、无返回值,自动调用于对象销毁时。
核心作用释放动态资源(如new内存、文件句柄),防止内存泄漏。
默认行为未定义时编译器生成空析构函数,仅适用于无动态资源的类。
继承场景析构顺序与构造顺序相反(派生类→基类),确保资源正确释放。
最佳实践结合 RAII 模式,或使用智能指针简化资源管理,避免手动编写繁琐析构逻辑。

通过合理设计析构函数,开发者能有效管理对象生命周期,确保程序的稳定性和资源利用率。下一节将深入探讨this指针与静态成员,进一步理解类的内部机制。

五、this 指针:指向当前对象的 “隐形指针”

1. this 指针作用

  • 解决命名冲突:当成员变量与参数同名时,用this->成员名区分。
    class Person {
    private:
        char name[20];
        int age;
    public:
        void set_name(char* name) {
            strcpy(this->name, name);  // this->name是成员变量,name是参数
        }
    };
    

2. 隐含参数

  • 成员函数隐式包含this指针参数,调用时自动传递当前对象地址。
    Person p;
    p.set_name("Alice");  // 等价于 set_name(&p, "Alice")
    

3. 返回当前对象引用(链式调用)

class Counter {
private:
    int value;
public:
    Counter& add(int n) {
        value += n;
        return *this;  // 返回当前对象引用
    }
};

Counter c;
c.add(10).add(20);  // 链式调用,等价于 c.add(10); c.add(20);

六、静态成员:类级别的共享数据与函数

1. 静态成员变量

  • 定义:用static修饰,属于类而非对象,所有对象共享。

  • 初始化:必须在类外初始化,格式为类型 类名::变量名 = 初始值;

    class Student {
    public:
        static int total_students;  // 声明静态成员变量
    };
    int Student::total_students = 0;  // 类外初始化
    
  • 访问方式

    • 通过类名:Student::total_students
    • 通过对象:stu1.total_students(需公有权限)

2. 静态成员函数

  • 特点:只能访问静态成员(变量 / 函数),无this指针。
  • 应用场景:统计类的对象数量。
    class Student {
    public:
        static int get_total() {  // 静态成员函数
            return total_students;
        }
    };
    

七、const 成员:保护数据不被修改

1. const 成员变量

  • 初始化:必须通过构造函数初始化列表赋值,不可修改。
    class Math {
    private:
        const float PI;  // const成员变量
    public:
        Math() : PI(3.14f) {}  // 初始化列表赋值
    };
    

2. const 成员函数(常成员函数)

  • 语法:在函数声明后加const,保证不修改成员变量。
    class Circle {
    private:
        float radius;
    public:
        float get_radius() const {  // 常成员函数
            return radius;  // 不可修改radius
        }
    };
    

3. const 对象

  • 定义const 类名 对象名;,只能调用常成员函数。
    const Circle c(5.0);
    c.get_radius();  // 合法,调用常成员函数
    // c.set_radius(6.0);  // 非法,set_radius非const函数
    

八、友元:打破访问权限的 “特权”

在 C++ 中,类的封装性通过public/protected/private严格控制成员访问,但有时需要允许特定的函数或类突破这种限制,直接访问私有成员。** 友元(Friend)** 机制就是为此设计的 “特权通道”,它允许非类成员函数或其他类的成员函数访问当前类的私有 / 保护成员。

1. 友元函数

友元函数是获得类访问特权的非成员函数,分为两种类型:全局非成员友元函数和其他类的成员友元函数。

(1)非成员友元函数
定义与声明
  • 作用:允许一个全局函数(不属于任何类)访问类的私有 / 保护成员。
  • 声明方式:在类体内用friend关键字声明函数原型,格式为:
    friend 返回值类型 函数名(参数列表);  
    
  • 关键特性:友元函数不是类的成员,无需通过对象调用,但可访问类的所有成员。
示例:访问银行账户余额(私有成员)
#include <iostream>  
using namespace std;  

class BankAccount {  
private:  
    float balance;  // 私有成员:账户余额  

public:  
    // 声明全局函数display_balance为友元  
    friend void display_balance(const BankAccount& acc);  

    // 构造函数初始化余额  
    BankAccount(float bal) : balance(bal) {}  
};  

// 友元函数定义:可直接访问私有成员balance  
void display_balance(const BankAccount& acc) {  
    cout << "账户余额:" << acc.balance << " 元" << endl;  
}  

int main() {  
    BankAccount account(10000.5f);  
    display_balance(account);  // 合法!友元函数访问私有成员  
    return 0;  
}  
代码解析
  • 友元声明friend void display_balance(...)在类内声明,赋予该函数访问私有成员balance的权限。
  • 参数传递:使用const引用传递对象,避免拷贝构造,提高效率并防止修改原始对象。
(2)其他类的成员友元函数
应用场景

当类 B 的某个成员函数需要访问类 A 的私有成员时,可将该成员函数声明为类 A 的友元。

声明方式
class A {  
private:  
    int private_data;  
public:  
    // 声明类B的成员函数B::friend_func为友元  
    friend void B::friend_func(A& obj);  
};  

class B {  
public:  
    void friend_func(A& obj) {  
        obj.private_data = 100;  // 合法!访问A的私有成员  
    }  
};  
示例:类间协作访问私有成员
#include <iostream>  
using namespace std;  

class Teacher;  // 前向声明,解决类依赖  

class Student {  
private:  
    int student_id;  
public:  
    // 声明Teacher类的成员函数Teacher::view_id为友元  
    friend void Teacher::view_id(Student& stu);  

    Student(int id) : student_id(id) {}  
};  

class Teacher {  
public:  
    void view_id(Student& stu) {  
        cout << "学生ID:" << stu.student_id << endl;  // 访问私有成员  
    }  
};  

int main() {  
    Student stu(20230001);  
    Teacher teacher;  
    teacher.view_id(stu);  // 教师类成员函数访问学生类私有ID  
    return 0;  
}  
注意事项
  • 前向声明:若友元函数所属的类未定义,需提前声明(如class Teacher;),但不能访问其成员细节。
  • 单向特权:仅被声明的成员函数拥有访问权,类 B 的其他成员函数仍无权限。

2. 友元类

定义与声明
  • 作用:将整个类 B 声明为类 A 的友元,类 B 的所有成员函数均可访问类 A 的私有 / 保护成员。
  • 声明方式:在类 A 内用friend class B;声明类 B 为友元。
示例:友元类访问私有成员
#include <iostream>  
using namespace std;  

class Library;  // 前向声明  

class Book {  
private:  
    string title;  
    int page_count;  

public:  
    Book(string t, int p) : title(t), page_count(p) {}  
    // 声明Library为友元类  
    friend class Library;  
};  

class Library {  
public:  
    void display_book_info(Book& b) {  
        // 访问Book的私有成员  
        cout << "书名:" << b.title << ", 页数:" << b.page_count << endl;  
    }  
};  

int main() {  
    Book book("C++ Primer", 1000);  
    Library lib;  
    lib.display_book_info(book);  // 合法!友元类成员函数访问私有成员  
    return 0;  
}  
友元类的特性
  1. 单向性

    • 若 A 是 B 的友元类,B 不一定是 A 的友元类,除非 A 也声明 B 为友元。
    class A { friend class B; };  // A允许B访问自己的私有成员  
    class B { friend class A; };  // 需额外声明,B才允许A访问自己的私有成员  
    
  2. 不可传递性

    • 若 B 是 A 的友元,C 是 B 的友元,C 并非自动成为 A 的友元。
  3. 破坏封装性

    • 友元类可访问所有私有成员,打破类的封装边界,需谨慎使用(仅在必要的类间协作时使用)。

3. 友元的优缺点与最佳实践

(1)核心优势
  • 灵活协作:允许类间高效交互,避免通过公有接口间接访问(如性能敏感场景)。
  • 保留封装性:仅对特定函数 / 类开放权限,而非完全公开私有成员。
(2)潜在风险
  • 耦合度增加:友元关系会强化类间依赖,修改一方可能影响另一方。
  • 调试难度:私有成员的访问点分散在友元函数 / 类中,难以追踪。
(3)使用建议
  1. 最小特权原则:优先声明单个友元函数而非整个友元类,缩小特权范围。
  2. 文档说明:在友元声明处注释说明原因,提高代码可读性。
  3. 避免滥用:仅在必要时使用(如运算符重载、类间数据共享),优先通过公有接口实现。

总结:友元核心知识点

类型定义声明方式访问权限
非成员友元函数全局函数,通过friend声明获得类私有成员访问权friend void func(类对象);可访问类的所有成员(含私有)
成员友元函数其他类的成员函数,声明后可访问当前类私有成员friend void 类B::func(类A对象);仅该成员函数拥有访问权
友元类整个类的所有成员函数可访问当前类私有成员friend class 类B;类 B 的所有成员函数均有访问权

友元机制是 C++ 封装性的补充,合理使用能在保持代码结构的同时实现高效交互。但需注意控制特权范围,避免过度依赖,确保代码的可维护性和安全性。下一章节将深入探讨拷贝构造函数与对象复制,理解对象创建的深层机制。

九、拷贝构造函数:对象的 “复制粘贴”

1. 自定义拷贝构造函数

  • 语法:参数为当前类的const引用,避免递归调用。
    class String {
    private:
        char* str;
    public:
        String(char* s) {  // 普通构造函数
            str = new char[strlen(s)+1];
            strcpy(str, s);
        }
        String(const String& obj) {  // 拷贝构造函数
            str = new char[strlen(obj.str)+1];
            strcpy(str, obj.str);  // 深拷贝,避免浅拷贝问题
        }
        ~String() { delete[] str; }
    };
    

2. 默认拷贝构造函数

  • 自动生成:若未定义,编译器生成默认版本(浅拷贝),适用于无动态资源的类。
  • 风险:若类包含动态内存,默认拷贝会导致多个对象指向同一块内存,释放时崩溃。

3. 调用场景

  • 对象初始化:String s2 = s1; 或 String s2(s1);
  • 函数传参:void func(String obj); 调用时复制实参对象。
  • 函数返回:String func() { String s; return s; } 返回时复制对象。

十、总结:类与对象核心知识点

概念关键特性
类的定义封装数据与行为,通过public/protected/private控制访问权限。
对象初始化构造函数(含参数、初始化列表、重载),自动调用,初始化成员数据。
资源管理析构函数释放资源,避免内存泄漏,与构造函数成对出现。
数据共享静态成员(变量 / 函数)属于类,所有对象共享,类外初始化。
权限突破友元函数 / 类可访问私有成员,打破封装限制,需谨慎使用。
对象复制拷贝构造函数实现深拷贝,避免默认浅拷贝的内存问题。
类型安全const 成员保证数据不被修改,常对象仅能调用常成员函数。

通过以上知识点,我们掌握了 C++ 类与对象的核心机制,从封装数据到管理对象生命周期,再到灵活处理对象间的关系。后续将深入学习继承与多态,进一步体会面向对象编程的强大能力。

相关文章:

  • 使用Mybatis时在XML中SQL高亮显示的方法
  • CExercise_10_2动态内存分配_1从键盘输入输入中读取一个整数n,动态分配一个长度为n的整型数组。
  • gcd之和
  • OpenCV 伪彩色处理
  • Linux 系统管理常用命令
  • RV1126 实现简单的UI方案
  • 【C++进阶】关联容器:multiset类型
  • Python代码解释
  • OpenCV 图形API(26)图像滤波-----方框滤波函数boxFilter()
  • SpringBoot系列之集成Redisson实现布隆过滤器
  • FastAPI全面指南:从入门到企业级应用实战
  • Java并发编程:深入解析原子操作类与CAS原理
  • SSH配置优化:提升本地内网Linux服务器远程连接速度与稳定性
  • 如何启动spark
  • 质因数之和-蓝桥20249
  • 纸质包装盒纸箱包裹损坏缺陷检测数据集VOC+YOLO格式2397张2类别
  • C++二分查找
  • sysfs 设备模型
  • 人工智能图像识别Spark Core3
  • Mysql中的数据类型和语句概述
  • seo优化操作/四川seo多少钱
  • 建筑招工哪个平台靠谱/开封搜索引擎优化
  • 网站网站制作网站/互联网推广话术
  • 河北汉佳 做网站的公司/seo课程
  • 中国最大房产网站排名/广告公司起名大全最新
  • 广州宝安建网站/搜图片找原图