C++成员函数和运算符的重载
<上一节
下一节>
构造函数的重载
构造函数可以重载,使得生成实例时非常方便。构造函数一般要对成员变量赋初值,有两种写法:#include <iostream> #include <string> using namespace std; class stuff { string name; int age; public: stuff() { //这是写法一 cout << name << "---" << age << endl; name = "空"; age = 0; cout << name << "---" << age << endl; } stuff(string n, int a):name(n),age(a) //这是写法二 { cout << name << "---" << age << endl; } string getName() { return name; } int getAge() { return age; } }; int main ( ) { stuff st2; stuff st1("C语言中文网", 3); return 0; }运行结果:
---2817728
空---0
C语言中文网---3
写法一是在构造函数体中赋值,赋值前成员变量已经有了地址空间,尚未有值。写法二是一种特殊方法,是在成员变量分配空间的同时将参数的值赋给成员变量。虽然写法二用的人少,但明显优于写法一。
事实上,如果将成员变量的定义改为常量,“const string name;”和“const int age;”,写法一将出错,而写法二仍然正确。
运算符重载
运算符重载对于普通函数和成员函数来说,格式稍有不同。//单目运算符 成员函数: 返回值类型 operator 运算符 () ; 普通函数: 返回值类型 operator 运算符 (对象的类型) ; //双目运算符 成员函数: 返回值类型 operator 运算符 (对象的类型) ; 普通函数: 返回值类型 operator 运算符 (对象的类型1, 对象的类型2) ; //函数调用 成员函数: 返回值类型 operator (任意的参数列) ; //数组元素 成员函数: 返回值类型 operator[] (参数类型) ; //增1/减1运算符 成员函数: 返回值类型 operator 运算符 (int) ; 普通函数: 返回值类型 operator 运算符 (对象的类型, int) ;
#include <iostream> #include <string> using namespace std; class stuff { string name; int age; public: stuff(string n, int a):name(n),age(a) { cout << name << "---" << age << endl; } string getName() { return name; } int getAge() { return age; } void operator +(int x); //运算符重载的定义 void operator +(string s); //运算符重载的定义 }; void stuff::operator +(int x) //运算符重载的实装 { age = age + x; } void stuff::operator +(string s) //运算符重载的实装 { name = name + s; } int main ( ) { stuff st2("C语言中文网", 3); st2 + 2; //+运算 st2 + ".C++ 60分钟入门教程"; //+运算 cout << st2.getName() << st2.getAge() << endl; return 0; }运行结果:
C语言中文网---3
C语言中文网.C++ 60分钟入门教程5
拷贝构造函数和赋值运算符
下面的代码略有深度,初学者如果无法理解可以跳过。“拷贝构造函数”和“赋值运算符”都是将对象的值复制一份然后传给另一对象。这二个功能也是类本身就具有的,但有很多场合原封不动地复制给另外一个对象时反而会出错,例如在成员函数中有动态分配内存,或者参数指针指向外部某一地址时,就有可能出错。
要避免这些错误,我们可以重载“=”运算符以及拷贝构造函数,将出错的因素排除。下例中为了演示,故意将赋值运算符重载函数中不复制“姓名”,而拷贝构造函数中固定“年龄”。
#include <iostream> #include <string> using namespace std; class stuff { string name; int age; public: stuff(string n, int a):name(n),age(a) { cout << "构造函数 " << name << age << endl; } string getName() { return name; } int getAge() { return age; } stuff& operator =(stuff& x); //赋值运算符重载 stuff(stuff& x):name(x.name),age(20) //拷贝构造函数重载 { cout << "拷贝构造函数 " << name << age << endl; } }; stuff& stuff::operator =(stuff& x) { age = x.age; cout << "赋值运算符 " << name << age << endl; return *this; } int main ( ) { stuff st("C语言中文网", 3); //调用通常的构造函数 stuff st1("C++ 60入门教程", 2); //调用通常的构造函数 st1 = st; //因为不产生新的实例,所以调用的是赋值运算符 stuff st2 = st; //因为产生新的实例,所以调用的是拷贝构造函数 cout << st.getName() << st.getAge() << endl; cout << st1.getName() << st1.getAge() << endl; cout << st2.getName() << st2.getAge() << endl; return 0; }运行结果:

类型转换
当需要将当前类的实例直接赋值给其它类型的变量时自动转换类型,这其实还是运算符重载。当需要其它类型直接赋值给当前类的实例时,只要增加构造函数就行。#include <iostream> #include <string> using namespace std; class stuff { string name; int age; public: stuff(string n, int a):name(n),age(a) { } string getName() { return name; } int getAge() { return age; } operator int() { //stuff → int return age; } operator string() { //stuff → string return name; } }; int main ( ) { stuff st("C语言中文网", 3); string m_name = st; //stuff → string int m_age = st; //stuff → int cout << m_name << endl; cout << m_age << endl; return 0; }运行结果:
C语言中文网
3
<上一节
下一节>