解码常对象与运算符重载

常对象与常对象成员

常对象

定义

const 修饰的类对象称为常对象,核心是对象的所有数据成员具备只读属性,且必须在定义时完成初始化。有两种等价的定义格式:

const 类名 对象名(初始化参数);  // 标准格式
类名 const 对象名(初始化参数);  // 等价格式

核心特性

  • 必须初始化:定义时需通过类的构造函数完成初始化,不能后续赋值;
  • 数据不可变:所有非 mutable 数据成员变为只读,无法通过常对象修改;
    • mutable 是 C++ 专属关键字,仅用于修饰类的非静态数据成员,核心作用是豁免 const 的只读限制
  • 调用限制:只能调用类的 const 成员函数(避免函数修改数据),无法调用非常成员函数。

示例代码

#include <iostream>
using namespace std;

class Cube {
public:
    int A, B;  // 普通数据成员

    /**
     * @brief 默认构造函数,初始化Cube对象的A和B
     * @return 无返回值(构造函数无返回类型)
     * @note 常对象若使用默认构造,也需确保数据成员被初始化
     */
    Cube() : A(11), B(22) {
        cout << "默认构造函数执行" << endl;
    }

    /**
     * @brief 参数化构造函数,自定义初始化Cube对象的A和B
     * @param a 初始化数据成员A的整数值
     * @param b 初始化数据成员B的整数值
     * @return 无返回值(构造函数无返回类型)
     * @note 常对象必须通过构造函数完成初始化,此为最常用方式
     */
    Cube(int a, int b) : A(a), B(b) {
        cout << "参数化构造函数执行" << endl;
    }

    /**
     * @brief 常成员函数,展示Cube对象的A和B值
     * @return 无返回值
     * @note const修饰表示该函数不修改对象数据,仅读取,可被常对象调用
     */
    void show() const {
        cout << "A=" << A << ", B=" << B << endl;
        // A = 100;  // 错误:常成员函数不能修改数据成员
    }

    /**
     * @brief 非常成员函数,尝试修改数据成员
     * @return 无返回值
     * @note 常对象无法调用此函数,仅非常对象可调用
     */
    void modify(int a, int b) {
        A = a;
        B = b;
    }
};

int main() {
    // 正确:常对象通过参数化构造初始化
    const Cube obj(10, 20);
    // obj.A = 30;  // 错误:常对象的Data成员只读,无法修改
    // obj.modify(5,6);  // 错误:常对象不能调用非常成员函数
    obj.show();  // 正确:常对象可调用常成员函数

    // 非常对象:可调用常/非常成员函数
    Cube obj2;
    obj2.modify(33, 44);  // 调用非常成员函数修改数据
    obj2.show();          // 调用常成员函数展示数据

    return 0;
}

常对象成员

常对象成员分为常数据成员常成员函数,是类中限制数据修改、保证代码健壮性的核心机制。

常数据成员

定义

const 修饰的类数据成员,代表该成员在对象生命周期内不可修改

核心规则

必须通过构造函数的初始化列表初始化,不能在构造函数体内部赋值(构造函数体执行时,数据成员已完成初始化,const 成员无法二次赋值)。

示例代码

#include <iostream>
using namespace std;

class Test {
private:
    /**
     * @brief 常数据成员,代表对象的唯一标识,生命周期内不可修改
     * @note 必须通过构造函数初始化列表赋值,无法在构造函数体修改
     */
    const int ID;

public:
    /**
     * @brief 构造函数,初始化常数据成员ID
     * @param id 初始化ID的整数值
     * @return 无返回值(构造函数无返回类型)
     * @note 常数据成员ID必须放在初始化列表中初始化,此为唯一合法方式
     */
    Test(int id) : ID(id) {
        // ID = id;  // 错误:构造函数体中无法给const成员赋值
    }

    /**
     * @brief 常成员函数,获取常数据成员ID的值
     * @return int 返回ID的整数值
     * @note 仅读取数据,不修改,符合常成员函数规则
     */
    int getID() const {
        return ID;
    }
};

int main() {
    Test t1(1001);  // 正确:初始化常数据成员ID为1001
    cout << "ID: " << t1.getID() << endl;  // 输出:ID: 1001

    // Test t2;  // 错误:默认构造函数未初始化const成员ID
    return 0;
}

常成员函数

定义

函数声明末尾加 const 修饰的成员函数,本质是 “承诺该函数不会修改对象的非 mutable 数据成员”。

核心规则

  • 不能修改对象的非 mutable 数据成员;
  • 不能调用类中的非常成员函数(避免间接修改数据),但非常成员函数可调用常成员函数;
  • 常对象只能调用常成员函数,非常对象可调用常 / 非常成员函数;
  • const 可参与函数重载(区分常对象 / 非常对象的调用)。

示例代码

#include <iostream>
using namespace std;

class Account {
private:
    double balance;  // 账户余额(普通数据成员)

public:
    /**
     * @brief 构造函数,初始化账户余额
     * @param bal 初始余额的浮点数值
     * @return 无返回值(构造函数无返回类型)
     */
    Account(double bal) : balance(bal) {}

    /**
     * @brief 常成员函数,获取账户余额
     * @return double 返回当前账户余额
     * @note const修饰,承诺不修改balance,可被常对象调用
     */
    double getBalance() const {
        // balance = 0;  // 错误:常成员函数不能修改数据成员
        return balance;
    }

    /**
     * @brief 非常成员函数,修改账户余额
     * @param bal 新的账户余额值
     * @return 无返回值
     * @note 仅非常对象可调用,可调用常成员函数
     */
    void setBalance(double bal) {
        balance = bal;
        cout << "新余额:" << getBalance() << endl;  // 调用常成员函数
    }
};

// 常成员函数重载示例
class Demo {
public:
    /**
     * @brief 非常版本的func函数,供非常对象调用
     * @return 无返回值
     */
    void func() {
        cout << "普通版本func(非常对象调用)" << endl;
    }

    /**
     * @brief const版本的func函数,供常对象调用
     * @return 无返回值
     * @note const修饰,与普通版本构成重载,编译器根据对象类型匹配
     */
    void func() const {
        cout << "const版本func(常对象调用)" << endl;
    }
};

int main() {
    // 常对象调用常成员函数
    const Account acc1(1000.5);
    cout << "常对象账户余额:" << acc1.getBalance() << endl;
    // acc1.setBalance(2000);  // 错误:常对象不能调用非常成员函数

    // 非常对象调用常/非常成员函数
    Account acc2(500);
    acc2.setBalance(1500);  // 调用非常成员函数
    cout << "非常对象账户余额:" << acc2.getBalance() << endl;  // 调用常成员函数

    // 常成员函数重载测试
    Demo d1;         // 非常对象
    const Demo d2;   // 常对象
    d1.func();       // 匹配普通版本:输出"普通版本func(非常对象调用)"
    d2.func();       // 匹配const版本:输出"const版本func(常对象调用)"

    return 0;
}

运算符重载

基本概念

本质

运算符重载是特殊的函数重载,目的是让自定义类对象能像内置类型(int/float 等)一样使用运算符(如 +/>/= 等)。

语法格式

返回类型 operator运算符符号(参数列表);

核心限制(必须遵守)

  • 不能改变原运算符的优先级(如 + 始终低于 );
  • 不能改变原运算符的结合性(如 = 是右结合,+ 是左结合);
  • 不能使用默认参数(运算符操作数个数固定,默认参数会破坏逻辑);
  • 不能改变原运算符的操作数个数(如 + 是双目运算符,重载后仍需两个操作数);
  • 不能改变运算符的语义(如 + 不能实现减法逻辑);
  • 可重载用于:自定义类对象之间、自定义类对象与内置类型之间;
  • 不可重载的运算符. (成员访问)、.*(指向成员的指针访问)、::(作用域解析)、?:(三目条件)、sizeof(大小计算)。

典型运算符的实现方式

运算符重载主要有三种实现方式:成员函数友元函数普通函数,不同运算符适配不同方式(如 = 只能用成员函数)。

算术运算符(以 + 为例)

方式 1:成员函数实现

#include <iostream>
using namespace std;

class Vector {
private:
    int x, y;  // 向量的x、y分量

public:
    /**
     * @brief 构造函数,初始化向量的x、y分量
     * @param x 向量x分量的整数值
     * @param y 向量y分量的整数值
     * @return 无返回值(构造函数无返回类型)
     */
    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    /**
     * @brief 成员函数重载+运算符,实现两个向量相加
     * @param v 右操作数(待相加的另一个Vector对象)
     *          const:避免修改传入的对象;引用:避免拷贝,提升效率
     * @return Vector 返回两个向量相加后的新Vector对象
     * @note 成员函数隐含this指针(指向左操作数),因此仅需一个显式参数
     */
    Vector operator+(const Vector& v) const {
        // this->x 是左操作数的x,v.x是右操作数的x,相加后构造新对象返回
        return Vector(this->x + v.x, this->y + v.y);
    }

    /**
     * @brief 常成员函数,展示向量的x、y分量
     * @return 无返回值
     */
    void show() const {
        cout << "Vector(" << x << ", " << y << ")" << endl;
    }
};

int main() {
    Vector v1(1, 2), v2(3, 4);
    Vector v3 = v1 + v2;  // 等价于v1.operator+(v2)
    v3.show();  // 输出:Vector(4, 6)
    return 0;
}

方式 2:友元函数实现

#include <iostream>
using namespace std;

class Vector {
private:
    int x, y;  // 私有分量,需友元函数访问

    /**
     * @brief 友元函数重载+运算符,实现两个向量相加
     * @param v1 左操作数(第一个Vector对象)
     *          const:避免修改;引用:避免拷贝
     * @param v2 右操作数(第二个Vector对象)
     *          const:避免修改;引用:避免拷贝
     * @return Vector 返回相加后的新Vector对象
     * @note 友元函数无this指针,需显式传入两个操作数,可直接访问私有成员
     */
    friend Vector operator+(const Vector& v1, const Vector& v2);

public:
    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    void show() const {
        cout << "Vector(" << x << ", " << y << ")" << endl;
    }
};

// 友元函数的实现(类外定义,无需加Vector::)
Vector operator+(const Vector& v1, const Vector& v2) {
    return Vector(v1.x + v2.x, v1.y + v2.y);
}

int main() {
    Vector v1(1, 2), v2(3, 4);
    Vector v3 = v1 + v2;  // 等价于operator+(v1, v2)
    v3.show();  // 输出:Vector(4, 6)
    return 0;
}

方式 3:普通函数实现

#include <iostream>
using namespace std;

class Vector {
public:
    int x, y;  // 需公开数据成员,否则普通函数无法访问

    Vector(int x = 0, int y = 0) : x(x), y(y) {}

    void show() const {
        cout << "Vector(" << x << ", " << y << ")" << endl;
    }
};

/**
 * @brief 普通函数重载+运算符,实现两个向量相加
 * @param v1 左操作数(第一个Vector对象)
 *        const:避免修改;引用:避免拷贝
 * @param v2 右操作数(第二个Vector对象)
 *        const:避免修改;引用:避免拷贝
 * @return Vector 返回相加后的新Vector对象
 * @note 普通函数无this指针,需两个显式参数,仅能访问类的公有成员
 */
Vector operator+(const Vector& v1, const Vector& v2) {
    return Vector(v1.x + v2.x, v1.y + v2.y);
}

int main() {
    Vector v1(1, 2), v2(3, 4);
    Vector v3 = v1 + v2;  // 等价于operator+(v1, v2)
    v3.show();  // 输出:Vector(4, 6)
    return 0;
}

关系运算符(以 > 为例)

方式 1:成员函数实现

#include <iostream>
using namespace std;

class Person {
private:
    int age;  // 私有年龄成员

public:
    /**
     * @brief 构造函数,初始化Person的年龄
     * @param age 年龄整数值
     * @return 无返回值(构造函数无返回类型)
     */
    Person(int age) : age(age) {}

    /**
     * @brief 成员函数重载>运算符,比较两个Person的年龄
     * @param p 右操作数(待比较的另一个Person对象)
     *        const:避免修改;引用:避免拷贝
     * @return bool 比较结果:true表示当前对象年龄更大,false反之
     * @note 隐含this指针指向左操作数,访问私有成员age无需额外权限
     */
    bool operator>(const Person& p) const {
        return this->age > p.age;
    }
};

int main() {
    Person p1(25), p2(20);
    // 等价于p1.operator>(p2)
    if (p1 > p2) {
        cout << "p1年龄更大" << endl;  // 输出此内容
    }
    return 0;
}

方式 2:友元函数实现

#include <iostream>
using namespace std;

class Person {
private:
    int age;  // 私有年龄成员

    /**
     * @brief 友元函数重载>运算符,比较两个Person的年龄
     * @param p1 左操作数(第一个Person对象)
     *        const:避免修改;引用:避免拷贝
     * @param p2 右操作数(第二个Person对象)
     *        const:避免修改;引用:避免拷贝
     * @return bool 比较结果:true表示p1年龄更大,false反之
     * @note 无this指针,需两个显式参数,可直接访问私有成员age
     */
    friend bool operator>(const Person& p1, const Person& p2);

public:
    Person(int age) : age(age) {}
};

// 友元函数实现
bool operator>(const Person& p1, const Person& p2) {
    return p1.age > p2.age;
}

int main() {
    Person p1(25), p2(20);
    if (p1 > p2) {  // 等价于operator>(p1, p2)
        cout << "p1年龄更大" << endl;
    }
    return 0;
}

方式 3:普通函数实现

#include <iostream>
using namespace std;

class Person {
public:
    int age;  // 公开年龄成员,供普通函数访问

    Person(int age) : age(age) {}
};

/**
 * @brief 普通函数重载>运算符,比较两个Person的年龄
 * @param p1 左操作数(第一个Person对象)
 *        const:避免修改;引用:避免拷贝
 * @param p2 右操作数(第二个Person对象)
 *        const:避免修改;引用:避免拷贝
 * @return bool 比较结果:true表示p1年龄更大,false反之
 * @note 仅能访问类的公有成员,无this指针
 */
bool operator>(const Person& p1, const Person& p2) {
    return p1.age > p2.age;
}

int main() {
    Person p1(25), p2(20);
    if (p1 > p2) {  // 等价于operator>(p1, p2)
        cout << "p1年龄更大" << endl;
    }
    return 0;
}

赋值运算符(=

核心规则

= 只能以成员函数实现(C++ 语法强制规定),且必须实现深拷贝(避免浅拷贝导致的内存泄漏 / 重复释放)。

示例代码(深拷贝版)

#include <iostream>
#include <algorithm>  // 包含std::copy函数using namespace std;

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

public:
    /**
     * @brief 默认构造函数,初始化空数组
     * @return 无返回值(构造函数无返回类型)
     * @note data初始化为nullptr,size初始化为0,避免野指针
     */
    Array() : data(nullptr), size(0) {
        cout << "默认构造函数执行" << endl;
    }

    /**
     * @brief 析构函数,释放动态数组内存
     * @return 无返回值
     * @note 避免内存泄漏,必须释放data指向的堆内存
     */
    ~Array() {
        delete[] data;
        cout << "析构函数执行,释放内存" << endl;
    }

    /**
     * @brief 拷贝构造函数,实现深拷贝
     * @param other 待拷贝的源Array对象
     *        const:避免修改源对象;引用:避免递归拷贝
     * @return 无返回值(构造函数无返回类型)
     * @note 重新分配内存,拷贝源对象的数据,避免浅拷贝导致的内存共享
     */
    Array(const Array& other) : size(other.size) {
        // 分配新内存
        data = new int[size];
        // 拷贝源对象的数据到新内存
        std::copy(other.data, other.data + size, data);
        cout << "拷贝构造函数执行(深拷贝)" << endl;
    }

    /**
     * @brief 成员函数重载=运算符,实现深拷贝赋值
     * @param other 待拷贝的源Array对象
     *        const:避免修改源对象;引用:避免拷贝,提升效率
     * @return Array& 返回当前对象的引用,支持连续赋值(如a = b = c)
     * @note 核心步骤:1. 检查自赋值;2. 释放原有内存;3. 分配新内存;4. 拷贝数据;5. 返回自身引用
     */
    Array& operator=(const Array& other) {
        // 1. 检查自赋值(避免释放自身内存后拷贝)
        if (this != &other) {
            // 2. 释放当前对象的原有内存
            delete[] data;

            // 3. 分配新内存,匹配源对象大小
            size = other.size;
            data = new int[size];

            // 4. 拷贝源对象的数据到新内存
            std::copy(other.data, other.data + size, data);
            cout << "赋值运算符执行(深拷贝)" << endl;
        }
        // 5. 返回自身引用,支持连续赋值
        return *this;
    }

    /**
     * @brief 初始化数组数据(辅助函数)
     * @param arr 待拷贝的整型数组
     * @param s 数组大小
     * @return 无返回值
     */
    void init(int* arr, int s) {
        delete[] data;  // 释放原有内存
        size = s;
        data = new int[size];
        std::copy(arr, arr + size, data);
    }

    /**
     * @brief 展示数组内容(辅助函数)
     * @return 无返回值
     */
    void show() const {
        for (int i = 0; i < size; ++i) {
            cout << data[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    int arr1[] = {1, 2, 3};
    int arr2[] = {4, 5, 6, 7};
    Array a1, a2;

    a1.init(arr1, 3);
    a2.init(arr2, 4);

    a1 = a2;  // 调用赋值运算符(深拷贝)
    a1.show();  // 输出:4 5 6 7

    Array a3 = a2;  // 调用拷贝构造函数(非赋值运算符)
    a3.show();  // 输出:4 5 6 7

    return 0;
}

输入输出运算符(<</>>

输出运算符(<<):友元函数实现(推荐)

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

class Person {
private:
    string name;  // 私有姓名
    int age;      // 私有年龄

    /**
     * @brief 友元函数重载<<运算符,输出Person对象信息
     * @param os 输出流对象(如cout)
     *        引用:ostream对象无法拷贝(拷贝构造函数protected),必须传引用
     * @param p 待输出的Person对象
     *        const:避免修改;引用:避免拷贝
     * @return ostream& 返回输出流引用,支持连续输出(如cout << p1 << p2)
     * @note 无法用成员函数实现(成员函数的this指针会占据左侧操作数位置,而<<左侧需是ostream对象)
     */
    friend ostream& operator<<(ostream& os, const Person& p);

public:
    /**
     * @brief 构造函数,初始化Person的姓名和年龄
     * @param name 姓名字符串
     * @param age 年龄整数值
     * @return 无返回值(构造函数无返回类型)
     */
    Person(string name, int age) : name(name), age(age) {}
};

// 友元函数实现
ostream& operator<<(ostream& os, const Person& p) {
    os << "姓名:" << p.name << ",年龄:" << p.age;
    return os;  // 返回流引用,支持连续输出
}

int main() {
    Person p("张三", 25);
    // 等价于operator<<(cout, p),连续输出
    cout << p << " | 额外信息" << endl;  // 输出:姓名:张三,年龄:25 | 额外信息
    return 0;
}

输入运算符(>>):友元函数实现(推荐)

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

class Person {
private:
    string name;
    int age;

    /**
     * @brief 友元函数重载>>运算符,读取输入到Person对象
     * @param is 输入流对象(如cin)
     *        引用:istream对象无法拷贝,必须传引用
     * @param p 待赋值的Person对象
     *        引用:需要修改对象的成员,不能加const
     * @return istream& 返回输入流引用,支持连续输入(如cin >> p1 >> p2)
     */
    friend istream& operator>>(istream& is, Person& p);

public:
    Person() : name(""), age(0) {}

    void show() const {
        cout << "姓名:" << name << ",年龄:" << age << endl;
    }
};

// 友元函数实现
istream& operator>>(istream& is, Person& p) {
    // 读取姓名和年龄到p的私有成员
    is >> p.name >> p.age;
    return is;  // 返回流引用,支持连续输入
}

int main() {
    Person p;
    cout << "请输入姓名和年龄:";
    cin >> p;  // 等价于operator>>(cin, p)
    p.show();  // 输出输入的姓名和年龄
    return 0;
}

递增运算符(++

核心规则

  • 前置 ++:无参数,返回对象引用(支持连续递增 ++(++a));
  • 后置 ++:带 int 哑元参数(仅用于区分重载),返回对象副本(先返回原值,再自增)。

方式 1:成员函数实现

#include <iostream>
using namespace std;

class Counter {
private:
    int value;  // 计数器值

public:
    /**
     * @brief 构造函数,初始化计数器值
     * @param val 初始计数值,默认0
     * @return 无返回值(构造函数无返回类型)
     */
    Counter(int val = 0) : value(val) {}

    /**
     * @brief 成员函数重载前置++运算符,实现计数器自增
     * @return Counter& 返回当前对象的引用,支持连续递增
     * @note 先自增,再返回自身引用,无参数
     */
    Counter& operator++() {
        ++value;  // 先自增
        return *this;  // 返回自身引用
    }

    /**
     * @brief 成员函数重载后置++运算符,实现计数器自增
     * @param int 哑元参数(无实际意义,仅区分前置/后置重载)
     * @return Counter 返回自增前的对象副本
     * @note 先保存副本,再自增,最后返回副本
     */
    const Counter operator++(int) {
        Counter temp = *this;  // 保存当前状态(自增前的值)
        ++value;               // 自增
        return temp;           // 返回副本
    }

    /**
     * @brief 常成员函数,获取计数器值
     * @return int 当前计数值
     */
    int getValue() const {
        return value;
    }
};

int main() {
    Counter c(5);

    // 前置++:先自增,再取值
    ++c;
    cout << "前置++后:" << c.getValue() << endl;  // 输出:6

    // 后置++:先取值,再自增
    Counter c2 = c++;
    cout << "后置++后c的值:" << c.getValue() << endl;   // 输出:7
    cout << "后置++返回的c2值:" << c2.getValue() << endl;  // 输出:6

    // 连续前置++
    ++(++c);
    cout << "连续前置++后:" << c.getValue() << endl;  // 输出:9

    return 0;
}

方式 2:友元函数实现

#include <iostream>
using namespace std;

class Counter {
private:
    int value;

    /**
     * @brief 友元函数重载前置++运算符
     * @param c 待自增的Counter对象
     *        引用:需要修改对象,且避免拷贝
     * @return Counter& 返回对象引用,支持连续递增
     */
    friend Counter& operator++(Counter& c);

    /**
     * @brief 友元函数重载后置++运算符
     * @param c 待自增的Counter对象
     *        引用:需要修改对象,且避免拷贝
     * @param int 哑元参数,区分前置/后置
     * @return Counter 返回自增前的对象副本
     */
    friend Counter operator++(Counter& c, int);

public:
    Counter(int val = 0) : value(val) {}

    int getValue() const {
        return value;
    }
};

// 前置++实现
Counter& operator++(Counter& c) {
    ++c.value;
    return c;
}

// 后置++实现
Counter operator++(Counter& c, int) {
    Counter temp = c;
    ++c.value;
    return temp;
}

int main() {
    Counter c(5);
    ++c;
    cout << "前置++后:" << c.getValue() << endl;  // 6

    Counter c2 = c++;
    cout << "后置++后c的值:" << c.getValue() << endl;   // 7
    cout << "后置++返回的c2值:" << c2.getValue() << endl;  // 6

    return 0;
}

右移运算符(>>

场景 1:位运算右移(成员函数实现)

#include <iostream>
using namespace std;

class BitMask {
private:
    int value;  // 位掩码值

public:
    /**
     * @brief 构造函数,初始化位掩码值
     * @param val 位掩码初始值
     * @return 无返回值(构造函数无返回类型)
     */
    BitMask(int val) : value(val) {}

    /**
     * @brief 成员函数重载>>运算符,实现位运算右移
     * @param shift 右移的位数(整数值)
     * @return BitMask 返回右移后的新BitMask对象
     * @note 隐含this指针指向左操作数(BitMask对象),右操作数是移位位数
     */
    BitMask operator>>(int shift) const {
        return BitMask(value >> shift);
    }

    /**
     * @brief 常成员函数,获取位掩码的十进制值
     * @return int 十进制值
     */
    int getValue() const {
        return value;
    }
};

int main() {
    BitMask bm(8);  // 8的二进制:1000
    BitMask bm2 = bm >> 2;  // 右移2位,二进制:0010(十进制2)
    cout << "右移2位后的值:" << bm2.getValue() << endl;  // 输出:2
    return 0;
}

运算符重载实现方式对比表

运算符 成员函数实现特点 友元函数实现特点 普通函数实现限制
+ 隐含 this 指针(左操作数),仅需 1 个显式参数;
可直接访问私有成员
无 this 指针,需 2 个显式参数;
可直接访问私有成员(需友元声明)
无 this 指针,需 2 个显式参数;
仅能访问公有成员
> 隐含 this 指针(左操作数),仅需 1 个显式参数;
可直接访问私有成员
无 this 指针,需 2 个显式参数;
可直接访问私有成员(需友元声明)
无 this 指针,需 2 个显式参数;
仅能访问公有成员
= 必须作为成员函数实现;
隐含 this 指针(左操作数);
支持深拷贝;
返回自身引用支持连续赋值
不允许(C++ 语法强制限制) 不允许(C++ 语法强制限制)
<<(输出流) 无法实现(左侧需是 ostream 对象,
成员函数的 this 指针会占据左侧位置)
标准实现方式;
无 this 指针,需 2 个显式参数;
可直接访问私有成员
需访问公有成员;
无 this 指针,需 2 个显式参数
>>(输入流) 无法实现(左侧需是 istream 对象) 标准实现方式;
无 this 指针,需 2 个显式参数;
可直接修改对象成员
需访问 / 修改公有成员;
无 this 指针,需 2 个显式参数
++ 前置无参数 / 后置带 int 哑元;
隐含 this 指针;
可直接访问私有成员
前置 / 后置参数与成员函数一致;
需友元声明;
可直接访问私有成员
需访问公有成员;
参数与友元函数一致
>>(位运算) 隐含 this 指针(左操作数),
右操作数为移位位数;
可直接访问私有成员
无 this 指针,需 2 个显式参数(对象 + 移位位数);
需友元声明
仅能访问公有成员;
需 2 个显式参数
posted @ 2025-12-07 20:32  YouEmbedded  阅读(1)  评论(0)    收藏  举报