C++

C++ 知识量:19 - 82 - 316

14.1 重载运算><

重载的运算符- 14.1.1 -

C++允许程序员重载大多数运算符,以使它们能够以自然和直观的方式执行于特定的类或类型。以下是一些可以被重载的运算符:

  • 算术运算符:+, -, *, /, %, ++, --

  • 关系运算符:<, <=, >, >=

  • 相等运算符:==, !=

  • 位运算符:&, |, ^, ~, <<, >>

  • 赋值运算符:=, +=, -=, *=, /=, %=, <<=, >>=

  • 逻辑运算符:&&, ||, !

  • 成员运算符:. (点), -> (箭头)

  • 地址运算符:&

  • 索引运算符:[]

  • 函数调用运算符:()

  • 类型转换运算符:static_cast<type>、dynamic_cast<type>、const_cast<type>、reinterpret_cast<type>

通过在类内部定义特定的成员函数或友元函数,可以对这些运算符进行重载。例如,以下是一个简单的例子,演示了如何重载加号运算符:

class Complex {  
public:  
    Complex(double real = 0.0, double imag = 0.0) : real_(real), imag_(imag) {}  
    Complex operator+(const Complex& other) const {  
        return Complex(real_ + other.real_, imag_ + other.imag_);  
    }  
private:  
    double real_;  
    double imag_;  
};

在这个例子中,定义了一个名为Complex的类,它代表了一个复数。重载了加号运算符,使其能够将两个Complex对象相加。

重载输出运算符<<- 14.1.2 -

在C++中,可以通过重载输出运算符 << 来定义自己的输出行为。这通常用于自定义类型的输出格式。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其输出运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass(int v) : value(v) {}  
  
    // 重载输出运算符  
    friend std::ostream& operator<<(std::ostream& os, const MyClass& obj) {  
        os << "MyClass: " << obj.value;  
        return os;  
    }  
};  
  
int main() {  
    MyClass obj(123);  
    std::cout << obj << std::endl; // 输出 "MyClass: 123"  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了输出运算符 <<,使其能够以定义的方式输出 MyClass 类型的对象。在重载的函数中,使用 std::ostream& 类型的参数,它代表了一个输出流。将输出流对象和 MyClass 对象作为参数,并返回一个 std::ostream& 类型的引用,以便可以连续使用输出运算符。在函数中,向输出流中插入了一个字符串 "MyClass: " 和 MyClass 对象的 value 成员变量,从而定义了输出的格式。最后,在 main 函数中创建了一个 MyClass 对象,并使用标准输出流 std::cout 输出了它。由于已经重载了输出运算符,所以输出的格式是定义的 "MyClass: " + value 的形式。

重载输入运算符>>- 14.1.3 -

在C++中,可以通过重载输入运算符 >> 来定义自己的输入行为。这通常用于自定义类型的输入格式。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其输入运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass() {}  
  
    // 重载输入运算符  
    friend std::istream& operator>>(std::istream& is, MyClass& obj) {  
        is >> obj.value;  
        return is;  
    }  
};  
  
int main() {  
    MyClass obj;  
    std::cin >> obj; // 输入整数并存储到obj.value中  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了输入运算符 >>,使其能够以定义的方式输入 MyClass 类型的对象。在重载的函数中,使用 std::istream& 类型的参数,它代表了一个输入流。将输入流对象和 MyClass 对象作为参数,并返回一个 std::istream& 类型的引用,以便可以连续使用输入运算符。在函数中,从输入流中提取了一个整数并将其存储到 MyClass 对象的 value 成员变量中,从而定义了输入的格式。最后,在 main 函数中创建了一个 MyClass 对象,并使用标准输入流 std::cin 输入了一个整数并将其存储到 obj.value 中。由于已经重载了输入运算符,所以输入的格式是定义的整数形式。

重载相等运算符- 14.1.4 -

在C++中,可以通过重载相等运算符(==)来定义自己的相等比较行为。这通常用于自定义类型的比较。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其相等运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass(int v) : value(v) {}  
  
    // 重载相等运算符  
    bool operator==(const MyClass& other) const {  
        return value == other.value;  
    }  
};  
  
int main() {  
    MyClass obj1(10);  
    MyClass obj2(20);  
    if (obj1 == obj2) {  
        std::cout << "obj1 is equal to obj2" << std::endl;  
    } else {  
        std::cout << "obj1 is not equal to obj2" << std::endl;  
    }  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了相等运算符 ==,使其能够以定义的方式比较两个 MyClass 类型的对象。在重载的函数中,使用两个 MyClass 类型的常量引用作为参数,并返回一个布尔值。在函数中,比较了两个对象的 value 成员变量,如果它们相等,则返回 true,否则返回 false。最后,在 main 函数中创建了两个 MyClass 对象,并使用重载的相等运算符比较它们是否相等。根据比较结果,输出相应的消息。

重载关系运算符- 14.1.5 -

在C++中,可以通过重载关系运算符(如 <, <=, >, >=)来定义自己的比较规则。这通常用于自定义类型的比较。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其关系运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass(int v) : value(v) {}  
  
    // 重载小于运算符  
    bool operator<(const MyClass& other) const {  
        return value < other.value;  
    }  
  
    // 重载小于等于运算符  
    bool operator<=(const MyClass& other) const {  
        return value <= other.value;  
    }  
  
    // 重载大于运算符  
    bool operator>(const MyClass& other) const {  
        return value > other.value;  
    }  
  
    // 重载大于等于运算符  
    bool operator>=(const MyClass& other) const {  
        return value >= other.value;  
    }  
};  
  
int main() {  
    MyClass obj1(10);  
    MyClass obj2(20);  
    if (obj1 < obj2) {  
        std::cout << "obj1 is less than obj2" << std::endl;  
    } else if (obj1 <= obj2) {  
        std::cout << "obj1 is less than or equal to obj2" << std::endl;  
    } else if (obj1 > obj2) {  
        std::cout << "obj1 is greater than obj2" << std::endl;  
    } else if (obj1 >= obj2) {  
        std::cout << "obj1 is greater than or equal to obj2" << std::endl;  
    } else {  
        std::cout << "The objects are equal." << std::endl;  
    }  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了四个关系运算符,使其能够以定义的方式比较两个 MyClass 类型的对象。每个运算符都返回一个布尔值,表明两个对象的相对大小关系。最后,在 main 函数中,创建了两个 MyClass 对象,并使用重载的关系运算符来比较它们的大小关系。根据比较结果,输出相应的消息。

重载赋值运算符- 14.1.6 -

在C++中,可以通过重载赋值运算符(=)来定义自己的赋值行为。这通常用于自定义类型的赋值。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其赋值运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass(int v) : value(v) {}  
  
    // 重载赋值运算符  
    MyClass& operator=(const MyClass& other) {  
        value = other.value;  
        return *this;  
    }  
};  
  
int main() {  
    MyClass obj1(10);  
    MyClass obj2(20);  
    obj1 = obj2; // 调用重载的赋值运算符  
    std::cout << "obj1.value: " << obj1.value << std::endl; // 输出:obj1.value: 20  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了赋值运算符 =,使其能够以定义的方式将一个 MyClass 类型的对象赋值给另一个。在重载的函数中,使用了 MyClass 类型的引用作为返回类型,并返回了 *this 的引用。这使得可以连续使用赋值运算符。在函数中,将右侧对象的 value 成员变量赋值给左侧对象,然后返回左侧对象的引用。最后,在 main 函数中,创建了两个 MyClass 对象,并使用重载的赋值运算符将一个对象赋值给另一个对象。然后输出了赋值后的对象的 value 成员变量的值。

重载下标运算符- 14.1.7 -

在C++中,可以通过重载下标运算符([])来定义自己的下标行为。这通常用于自定义类型的下标访问。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其下标运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value[10];  
  
    MyClass() {  
        for (int i = 0; i < 10; ++i) {  
            value[i] = i;  
        }  
    }  
  
    // 重载下标运算符  
    int& operator[](int index) {  
        return value[index];  
    }  
};  
  
int main() {  
    MyClass obj;  
    std::cout << "obj[2]: " << obj[2] << std::endl; // 输出:obj[2]: 2  
    obj[2] = 20;  
    std::cout << "obj[2]: " << obj[2] << std::endl; // 输出:obj[2]: 20  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量,它是一个大小为10的整型数组。然后重载了下标运算符 [],使其能够以定义的方式访问 value 数组中的元素。在重载的函数中,返回了 value 数组中指定索引位置的元素的引用。这使得可以使用下标运算符来访问和修改数组中的元素。在 main 函数中,创建了一个 MyClass 对象,并使用重载的下标运算符访问和修改了数组中的元素。最后,输出了修改后的数组中的元素的值。

重载递增和递减运算符- 14.1.8 -

在C++中,可以通过重载递增运算符(++)和递减运算符(--)来定义自己的递增和递减行为。这通常用于自定义类型的迭代器。

以下是一个简单的例子,定义了一个 MyClass 类,并重载了其递增和递减运算符:

#include <iostream>  
  
class MyClass {  
public:  
    int value;  
  
    MyClass(int v) : value(v) {}  
  
    // 重载递增运算符  
    MyClass& operator++() {  
        ++value;  
        return *this;  
    }  
  
    // 重载递减运算符  
    MyClass& operator--() {  
        --value;  
        return *this;  
    }  
};  
  
int main() {  
    MyClass obj(10);  
    std::cout << "obj.value: " << obj.value << std::endl; // 输出:obj.value: 10  
    ++obj; // 调用重载的递增运算符  
    std::cout << "obj.value: " << obj.value << std::endl; // 输出:obj.value: 11  
    --obj; // 调用重载的递减运算符  
    std::cout << "obj.value: " << obj.value << std::endl; // 输出:obj.value: 10  
    return 0;  
}

在这个例子中,定义了一个 MyClass 类,包含一个 value 成员变量。然后重载了递增运算符 ++ 和递减运算符 --,使其能够以定义的方式递增和递减 value 变量的值。在重载的函数中,使用了 MyClass 类型的引用作为返回类型,并返回了 *this 的引用。这使得可以连续使用递增和递减运算符。在函数中,递增或递减 value 变量的值,并返回 *this 的引用,以便可以连续使用这些运算符。在 main 函数中,创建了一个 MyClass 对象,并使用重载的递增和递减运算符来递增和递减 value 变量的值。最后,输出了修改后的 value 变量的值。