网站公司倒闭,flash 网站头部,服务器做内网网站,网站模版 带 手机版1、什么是运算符重载#xff1f; 运算符重载是 C 中的一项功能#xff0c;使运算符#xff08;例如 、- 等#xff09;能够处理用户定义的数据类型。这种机制称为编译时多态性#xff0c;并提供了为不同数据类型定制运算符行为的优点。 例如#xff0c;我们可以重载“”运…1、什么是运算符重载 运算符重载是 C 中的一项功能使运算符例如 、- 等能够处理用户定义的数据类型。这种机制称为编译时多态性并提供了为不同数据类型定制运算符行为的优点。 例如我们可以重载“”运算符来执行整数加法、字符串串联以及复数加法。这增强了运算符的多功能性使他们能够对更广泛的数据类型进行操作。
2、什么是运算符函数 运算符函数是一种专门类型的函数它为特定运算符提供替代实现。它的语法与常规函数类似但其名称以“operator”关键字开头后跟运算符符号。 我们可以为同一个运算符定义多个运算符函数这些函数可以根据它们所使用的操作数的数量和类型来区分。例如“”运算符可以针对整数、字符串和复数具有不同的运算符函数实现。这允许对操作员进行定制以满足特定要求。
class ClassName
{...publicReturnType operator OperatorSymbool(argument list) {// Implementation logic} ...
}; ReturnType 运算符函数返回值的类型。 运算符编程语言中用于执行特定操作的关键字。 OperatorSymbol程序中重载的运算符的符号。 参数列表调用函数时传递给函数的参数列表。 3、使用运算符重载将两个复数相加 假设我们不使用运算符重载并且想要将两个复数相加。我们可以通过创建一个名为“Complex”的复数类来实现这一点。在类内部我们定义了一个名为“add”的公共方法它执行两个复数的加法。此方法将接受两个复数作为参数并将它们相加的结果作为新的复数返回。
class Complex {public:Complex add(Complex c1, Complex c2) {// Perform addition of c1 and c2 and return the resultreturn result;}
};//This approach works.
//But it requires us to call add method
Complex c1, c2, res;
res c1.add(c1, c2); 众所周知运算符重载允许我们更改运算符的行为以处理用户定义的数据类型。因此对于复数重载“”运算符我们可以在“Complex”类中定义一个运算符重载函数。 此函数将指定“”运算符与复数一起使用时的新行为。该函数可以定义为类的成员函数或友元函数具体取决于运算符及其所操作的操作数的具体要求。 定义完运算符函数后我们现在可以使用简单的语句将两个复数 c1 和 c2 相加res c1 c2这相当于 res c1.operator (c2)。这使得代码更直观、更容易理解。
#include iostream
using namespace std;class Complex {private:int real, imag;public:Complex(int r 0, int i 0) {real r;imag i;}Complex operator (Complex c) {Complex temp;temp.real real c.real;temp.imag imag c.imag;return temp;}int getReal(){return real;}int getImag(){return imag;}
};int main() {Complex c1(4, 7);Complex c2(3, 5);Complex res;res c1 c2;cout Result: res.getReal() res.getImag() i endl;return 0;
}//output Result: 7 12i 我们还可以将函数签名写成如下
Complex operator (const Complex c) 这个版本与之前的版本有几个显着的区别
参数“c”使用“”运算符通过引用传递这意味着该函数将接收到原始对象的直接链接而不是副本。参数“c”也被指定为“const”表示该函数不能更改它所传递的对象。 这些修改被认为是最佳实践原因如下
通过引用传递对象函数可以访问原始对象而无需创建重复对象从而提高效率并避免创建新对象的不必要的开销。将对象指定为“const”有助于防止对该对象进行意外修改从而降低代码中出现错误和意外行为的风险。 4、重载加法运算符的另一个例子
class opr
{private:int a;float b;public:opr(int a, float b) {this-a a;this-b b;}opr operator (opr test) {opr tmp(0, 0.0);tmp.a a test.a;tmp.b b test.b;return tmp;}void show() {cout a b \n;}
};int main()
{opr obj1(1, 3.3);opr obj2(2, 1.5);opr obj3;obj3 obj1 obj2;obj3.show();return 0;
}
5、运算符重载的一些规则 在 C 中重载运算符时需要记住几个重要规则 1、至少其中一个操作数必须是用户定义的数据类型。 2、只有内置运算符才能重载。这意味着我们无法创建新的运算符只能更改现有的运算符以使其工作方式不同。 3、重载运算符不能有默认参数空参数列表“()”除外。 4、重载运算符不会影响其优先级或结合性。 5、操作数的数量无法更改。例如一元运算符保持一元二元运算符保持二元。 6、编译器会自动为每个类重载赋值运算符“”。换句话说不需要为赋值运算符创建单独的运算符函数。我们可以使用它来复制同一类的对象类似于使用复制构造函数。 7、重载运算符时正确且一致地使用它们以使代码更具可读性和易于理解性至关重要。
6、一元运算符的运算符重载 一元运算符是对单个操作数进行操作的运算符。自增运算符“”和自减运算符“--”是一元运算符的示例。例如增量运算符“”将其操作数的值增加1。它可以用作前缀运算符放置在操作数之前或后缀运算符放置在操作数之后。 例如
int x 5;
// x is incremented to 6, and y is set to 6
int y x;
// x is incremented to 7, but z is set to the original value of x (6)
int z x; 类似地减运算符“--”将其操作数的值减1。它也可以用作前缀或后缀运算符。例如
int x 5;
// x is decremented to 4, and y is set to 4
int y --x;
// x is decremented to 3, but z is set to the original value of x (4)
int z x--;
7、重载自增运算符()的实现代码 在下面的代码中我们定义了一个名为“Value”的类其中包含一个私有成员变量“count”。我们还定义了一个构造函数将该成员变量初始化为值 2。在类内部我们将“operator”函数定义为成员函数该函数被重载两次带和不带 int 参数。这些函数将“count”成员变量的值加 1。 在 main 函数中我们创建一个“Value”对象 (v) 并对其多次使用“”运算符。然后我们使用“getCount”方法来检索“count”成员变量的值。
class Value
{private:int count;public:Value() : count(2) {}// prefix version of operatorvoid operator () {count;}// postfix version of operatorvoid operator (int) {count;}int getCount() {return count;}
};int main()
{Value v;v;cout v.getCount() \n;v;v;cout v.getCount() \n;return 0;
}//output
//3
//5 一元运算符函数的前缀和后缀版本之间的唯一区别是参数列表。前缀版本不带参数而后缀版本带一个“int”类型的参数。该参数实际上并不用于传递整数值而是向编译器发出信号指示该函数应用于重载运算符的后缀形式。
8、C中实现运算符重载的三种方法 (1)、通过成员函数重载运算符 成员函数是在类内部定义并作用于该类的对象的函数。关于运算符重载一元运算符对单个参数进行操作的运算符在其列表中没有参数而二元运算符对两个参数进行操作的运算符只有一个参数。
class Complex
{private:double real;double imag;public:Complex(double real 0, double imag 0) : real(real), imag(imag) {}// overload the operator as a member functionComplex operator (const Complex other) const {return Complex(real other.real, imag other.imag);}void print() const {cout real imag i endl;}
};int main()
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 c1 c2;c3.print();return 0;
} (2)、通过友元函数重载运算符 友元函数不是类的成员但可以直接访问私有和受保护成员并且可以在类的私有或公共部分中声明。与成员函数相比它提供了更大的灵活性。 换句话说如果运算符函数需要访问类的私有和受保护成员则可以将其定义为友元函数。在这种情况下一元运算符有一个参数而二元运算符有两个参数。
class Complex
{private:double real;double imag;public:Complex(double real 0, double imag 0) : real(real), imag(imag) {}friend Complex operator (const Complex c1, const Complex c2);void print(){cout real imag i endl;}
};// overload the operator as a friend function
Complex operator (const Complex c1, const Complex c2)
{return Complex(c1.real c2.real, c1.imag c2.imag);
}int main()
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 c1 c2;c3.print();return 0;
} (3)、通过非成员函数重载运算符 非成员函数不是类的成员无权访问私有成员和受保护成员。
class Complex
{public:double real;double imag;Complex(double real 0, double imag 0) : real(real), imag(imag) {}void print() const {cout real imag i endl;}
};// overload the operator as a non-member function
Complex operator (const Complex c1, const Complex c2)
{return Complex(c1.real c2.real, c1.imag c2.imag);
}int main()
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 c1 c2;c3.print();return 0;
}