日志20
一、运算符重载
运算符重载是C++语言的一项强大功能,它允许程序员为自定义类型(如类或结构体)的对象定义运算符的行为。这意味着,我们可以像使用内置类型(如int、float等)的运算符一样,使用自定义类型的运算符。
重载规则
- C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
- 重载不能改变运算符运算对象(即操作数)的个数。例如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两个参数。
- 重载不能改变运算符的优先级别和结合性。例如,“*”和“/”优先级高于“+”和“-”,不论怎样进行重载,各运算符之间的优先级不会改变。
- 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。也就是说,参数不能全部是C++的标准类型,防止将原有的默认实现抵消。
重载方式
- 成员函数重载:当运算符重载为成员函数时,如果运算符参数只有一个,那么不需要写参数;如果运算符参数有两个,那么只需要写一个参数(因为类的成员函数默认有一个this指针,指向调用该函数的对象)。
- 友元函数重载:有时需要重载的运算符函数需要访问类的私有成员或保护成员,或者运算符的操作数涉及不同类型的对象,这时可以将运算符重载为友元函数。友元函数不是类的成员函数,但它可以访问类的私有成员和保护成员。
重载示例
class Complex { public: Complex(double r = 0, double i = 0) : real(r), imag(i) {} // 重载+运算符 Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } // 重载<<运算符(友元函数) friend ostream& operator<<(ostream& os, const Complex& c) { os << "(" << c.real << " + " << c.imag << "i)"; return os; } private: double real, imag; }; int main() { Complex c1(1, 2), c2(3, 4); Complex c3 = c1 + c2; cout << c3 << endl; // 输出: (4 + 6i) return 0; }
二、重载流插入运算符和流提取运算符
C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,用于标准类型的输入输出。对于用户自定义的类型,如果想用它们来输出和输入自定义类型的数据,必须对它们进行重载。
重载流插入运算符“<<”
重载流插入运算符通常将函数定义为类的友元函数,因为这样可以访问类的私有成员。函数的第一个参数和返回类型都必须是ostream&类型,第二个参数是要进行输出操作的类的引用。
class MyClass { public: MyClass(int x) : value(x) {} // 重载<<运算符(友元函数) friend ostream& operator<<(ostream& os, const MyClass& obj) { os << "MyClass value: " << obj.value; return os; } private: int value; };
重载流提取运算符“>>”
重载流提取运算符通常也将函数定义为类的友元函数。函数的第一个参数和返回类型都必须是istream&类型,第二个参数是要进行输入操作的类的引用。
class MyClass { public: MyClass() : value(0) {} // 重载>>运算符(友元函数) friend istream& operator>>(istream& is, MyClass& obj) { is >> obj.value; return is; } private: int value; };
三、不同类型数据间的转换
在C++中,数据类型转换是一个常见的操作。它允许程序员将一种数据类型的值转换为另一种数据类型的值。C++提供了多种类型转换方式,包括隐式类型转换、显式类型转换、C风格的类型转换以及C++风格的类型转换运算符。
隐式类型转换
隐式类型转换(也称为自动类型转换)是编译器在需要时自动进行的类型转换。例如,将float类型的值赋给int类型的变量时,小数部分会被截断。
int i = 3.14; // 隐式转换,3.14被截断为3
显式类型转换
- 显式类型转换是程序员明确指定的类型转换。C++提供了四种类型转换运算符:static_cast、dynamic_cast、const_cast和reinterpret_cast。static_cast:用于非多态类型的安全转换,如基本数据类型之间的转换,或者向上转型(从派生类指针转换为基类指针)。dynamic_cast:用于多态类型的安全向下转型(从基类指针转换为派生类指针),只有在存在继承关系并且至少有一个虚函数时才有效。const_cast:用于移除或添加const或volatile属性。reinterpret_cast:用于低级别的重新解释转换,可以将任何指针转换为任何其他指针类型,甚至可以将指针转换为足够大的整数类型。
- C风格的类型转换C风格的类型转换使用(type)value的形式进行类型转换。这种转换方式不安全,因为它不会进行类型检查,容易导致类型转换错误。在C++中,应尽量避免使用C风格的类型转换,而应使用C++风格的类型转换运算符。
int i = 10; float f = (float)i; // C风格转换
转换构造函数和类型转换函数
- 转换构造函数:允许将一个其他类型的数据转换成一个类的对象。
- 类型转换函数:允许将一个类的对象转换成另一类型的数据。这两个功能在C++中非常有用,它们允许程序员在自定义类型和其他类型之间进行灵活的转换。