C++ 运算符重载
运算符重载的本质还是函数重载,可以将运算符理解为特殊的函数名:
- 运算符重载时,运算顺序和优先级不变,操作数个数不变
- 不能创造新的操作符,并且规定下面的六个操作符不能重载
- 运算符重载函数不能有默认的参数
- 重载函数既可以作为类的成员函数,也可以作为全局函数(一般定义为友元函数)
箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符= 只能以成员函数的形式重载
可以重载的运算符基本可以分为:
可以重载的运算符.jpg
赋值运算符重载
只能以成员函数的形式重载,基本形式为:基本形式为 classname& operator=(classname& 实例对象)
注意输入参数只有一个,而且必须是对象的引用,返回值也必须是对象的引用
tips:可以将operator= 看成一个整体,当成函数名,赋值运算符重载函数也可以重载,即可以有多个
//声明
allOperatorDemo& operator=(allOperatorDemo& p);
allOperatorDemo& operator=(string str);
//定义
allOperatorDemo& allOperatorDemo::operator=(allOperatorDemo& p) {
mstr = p.mstr;
return *this;
}
allOperatorDemo& allOperatorDemo::operator=(string str) {
mstr = str;
mstr.append("=string_str");
return *this;
}
//使用
// 赋值运算符重载
{
allOperatorDemo p("init");
p = "hello";
cout << "p mstr: " << p.mstr << endl; // hello=string_str
allOperatorDemo q("demo");
p = q;
cout << "p mstr: " << p.mstr << endl; // demo
}
算术运算符重载
算术运算符包括+、++、–、- -、+=、-=、/、*等,作为成员函数重载的基本形式为:
classname& operator运算符(classname& 实例对象)
除了自增和自减运算符,其余算术运算符都是一个参数,返回值是对象的引用
- 全局运算符重载
friend classname& operator运算符(const classname& a,const classname& b) - 成员函数重载
classname& operator运算符(const classname& b)
tips: 运算符重载的参数可以任意定义,但是不能改变参数的个数
//声明
allOperatorDemo& operator+(allOperatorDemo& p);
allOperatorDemo& operator+(const char* str);
allOperatorDemo& operator-(allOperatorDemo& p);
allOperatorDemo& operator*(allOperatorDemo& p);
allOperatorDemo& operator/(allOperatorDemo& p);
allOperatorDemo& operator+=(allOperatorDemo& p);
allOperatorDemo& operator-=(allOperatorDemo& p);
allOperatorDemo& operator*=(allOperatorDemo& p);
allOperatorDemo& operator/=(allOperatorDemo& p);
//定义
allOperatorDemo& allOperatorDemo::operator+(allOperatorDemo& p) {
mstr.append(p.mstr);
return *this;
}
allOperatorDemo& allOperatorDemo::operator+(const char* str) {
mstr.append(str).append("operator+_const_str");
return *this;
}
allOperatorDemo& allOperatorDemo::operator-(allOperatorDemo& p) {
mstr.append("operator-");
return *this;
}
allOperatorDemo& allOperatorDemo::operator*(allOperatorDemo& p) {
mstr.append("operator*");
return *this;
}
.... //其余形式相同
注意算术运算符+,-,*,/ 的两种调用形式的区别
allOperatorDemo democ = demoa + demob 和
allOperatorDemo democ;
democ = demoa + demob;
第一种只会调用到 + 运算符重载,第二种先实例化了对象,会同时调用到赋值运算符和 + 运算符重载
调用形式如下:
// 算术运算符重载
{
allOperatorDemo p("init");
allOperatorDemo m("demo");
//allOperatorDemo q = p + "hello";
allOperatorDemo q = p + m;
cout << "p mstr: " << p.mstr << endl; //p mstr: initdemo
}
{
allOperatorDemo p("init");
allOperatorDemo m("m");
p += m;
cout << "p mstr: " << p.mstr << endl; // p mstr: initoperator+=
}
+,-,*,/ 重载函数调用完成之后,两个输入对象作为参数,本身没有发生变化
注意使用 +=,-= 等也属于赋值运算符,只能定义为成员函数
关系运算符重载
bool operator>(allOperatorDemo& p);
bool operator>(const char* str);
bool operator>=(allOperatorDemo& p);
bool operator<(allOperatorDemo& p);
bool operator<=(allOperatorDemo& p);
bool operator==(allOperatorDemo& p);
bool operator!=(allOperatorDemo& p);
bool allOperatorDemo::operator>(allOperatorDemo& p) {
return (mstr > p.mstr ? true : false);
}
bool allOperatorDemo::operator>(const char* str) {
return (mstr > str ? true : false);
}
bool allOperatorDemo::operator>=(allOperatorDemo& p) {
return (mstr >= p.mstr ? true : false);
}
关系运算符重载函数也是可以重载的,比如上面对 > 运算符的重载
调用形式:
// 关系运算符重载
{
allOperatorDemo p("init");
allOperatorDemo m("thismorning");
cout << "p(init) > m(this morning) " << (p > m) << endl;
cout << "p(init) >= m(this morning) " << (p >= m) << endl;
cout << "p(init) < m(this morning) " << (p < m) << endl;
cout << "p(init) <= m(this morning) " << (p <= m) << endl;
cout << "p(init) == m(this morning) " << (p == m) << endl;
cout << "p(init) != m(this morning) " << (p != m) << endl;
}
自增自减运算符重载
对于 p++ 和 ++p 这两种形式都是可以重载的,operator++(int) 对应于 p++这种形式,:operator++()对应于++p 这种形式
allOperatorDemo& operator++();
allOperatorDemo& operator++(int);
allOperatorDemo& operator--();
allOperatorDemo& operator--(int);
allOperatorDemo& allOperatorDemo::operator++() {
mstr.append("operator++");
return *this;
}
allOperatorDemo& allOperatorDemo::operator++(int) {
mstr.append("operator++_int");
return *this;
}
数组下标[ ] 运算符重载
只能以成员函数的形式重载
char operator[](uint32_t pos);
void operator[](string str);
char allOperatorDemo::operator[](uint32_t pos) {
return mstr[pos];
}
void allOperatorDemo::operator[](string str) {
mstr.append("[]_string_str");
}
{
allOperatorDemo p("init");
char c = p[2];
cout << "p[2]: " << c << endl; //p[2]: i
p["hello"];
cout << "p mstr: " << p.mstr << endl; //p mstr: init[]_string_str
}
赋值构造函数
赋值构造函数(Assignment Constructor)是一种特殊的构造函数,用于将一个已存在的对象的值赋给另一个对象;赋值构造函数通常用于实现对象的赋值语句
demoClass p;
demoClass q = p;
需要注意的是,赋值构造函数与拷贝构造函数不同,拷贝构造函数用于将一个对象的值复制到另一个对象中,而赋值构造函数用于将一个已存在的对象的值赋给另一个对象
赋值构造函数的原型与拷贝构造函数类似,但是它使用赋值运算符(=)来初始化一个对象,例如:
demoClass& operator=(const demoClass& obj)
如果一个类没有显式定义赋值构造函数,编译器会生成一个默认的赋值构造函数,但是这个默认的构造函数只是进行浅拷贝(也就是仅仅复制指针或者成员变量的值),这可能会导致对象之间的数据共享或者内存泄漏问题,因此在需要复制对象时,建议自行实现赋值构造函数
赋值构造函数和拷贝构造函数的区别:
-
拷贝构造函数是构造函数的一种,它没有返回值,在创建新对象的时候如果使用下面的形式定义对象,拷贝构造函数会被自动调用到
newkeyWordDemo p(10);
newkeyWordDemo q(p); -
赋值构造函数是 = 操作符的一种重载实现,参数是一个常量引用,返回值是对象的引用
newkeyWordDemo p(10);
newkeyWordDemo q = p;
网友评论