网站百度推广,网络架构如何写,杭州做网点卖服装在那个网站,网站建设公司发展理念4.提高
1.运算符重载机制 编译器实现运算符重载实际上就是通过函数重载实现的#xff0c;可分为全局函数方式#xff0c;也可分为成员函数方式进行重载#xff0c;并没有改变原操作符的属性和语义。只是针对某个特定类定义一种新的数据类型操作。 2.重载赋值运算符 赋值…4.提高
1.运算符重载机制 编译器实现运算符重载实际上就是通过函数重载实现的可分为全局函数方式也可分为成员函数方式进行重载并没有改变原操作符的属性和语义。只是针对某个特定类定义一种新的数据类型操作。 2.重载赋值运算符 赋值运算符重载用于对象数据的复制operator 必须重载为成员函数重载函数原型为 类型 类名 :: operator ( const 类名 ) ; 结论: 1 先释放旧的内存 2 返回一个引用 3 操作符 从右向左 #define _CRT_SECURE_NO_WARNINGS
#include iostream
using namespace std;//class Name
{
public:Name(const char *myp){m_len strlen(myp);m_p (char *) malloc(m_len 1); //strcpy(m_p, myp);}//Name obj2 obj1;//解决方案: 手工的编写拷贝构造函数 使用深copyName(const Name obj1){m_len obj1.m_len;m_p (char *)malloc(m_len 1);strcpy(m_p, obj1.m_p);}//obj3 obj1; // C编译器提供的 等号操作 也属 浅拷贝//obj3.operator(obj1)Name operator(Name obj1){//先释放旧的内存if (this-m_p ! NULL){delete[] m_p;m_len 0;}//2 根据obj1分配内存大小this-m_len obj1.m_len;this-m_p new char [m_len1];//把obj1赋值strcpy(m_p, obj1.m_p);return *this;}~Name(){if (m_p ! NULL){free(m_p);m_p NULL;m_len 0;}}
protected:
private:char *m_p ;int m_len;
};//对象析构的时候 出现coredump
void objplaymain()
{Name obj1(abcdefg);Name obj2 obj1; //C编译器提供的 默认的copy构造函数 浅拷贝Name obj3(obj3);obj3 obj1; // C编译器提供的 等号操作 也属 浅拷贝//obj3.operator(obj1)//operato(Name obj1)obj1 obj2 obj3;//obj2.operator(obj3);//obj1 void;
}void main()
{objplaymain();couthello...endl;system(pause);return ;
}
3.重载下标运算符
[ ]运算符用于访问数据对象的元素重载格式 类型 类 :: operator[] ( 类型 ) 只能用成员函数重载不能用友元函数重载
示例 设 x 是类 X 的一个对象则表达式 x [ y ] 可被解释为 x . operator [ ] ( y ) 函数返回值当左值需要返回一个引用 4.带下标和相等操作符的数组类
类的头文件
#ifndef NEWARRAY_H
#define NEWARRAY_H
#include iostream
#include stdlib.hclass NewArray
{
public:NewArray();NewArray(int _len);NewArray(const NewArray obj);~NewArray();void setData(int index,int var);int getData(int index);int length();int operator[](int i);NewArray operator(NewArray obj);bool operator(NewArray obj);bool operator!(NewArray obj);private:int m_len;int *m_buf;
};#endif // NEWARRAY_H
类的实现文件
#include newarray.hNewArray::NewArray()
{m_buf NULL;m_len -1;
}NewArray::NewArray(int _len)
{if(_len 0)_len 0;m_len _len;m_buf new int[m_len];}
NewArray::NewArray(const NewArray obj)
{m_len obj.m_len;m_buf new int[m_len];for(int i 0;i m_len;i){m_buf[i] obj.m_buf[i];}
}
NewArray::~NewArray()
{if(m_buf ! NULL){delete []m_buf;m_buf NULL;m_len -1;}
}void NewArray::setData(int index,int var)
{m_buf[index] var;
}
int NewArray::getData(int index)
{return m_buf[index];
}
int NewArray::length()
{return m_len;
}int NewArray::operator[](int i)
{return m_buf[i];
}
NewArray NewArray::operator(NewArray obj)
{if(m_buf ! NULL){delete []m_buf;m_len -1;m_buf NULL;}m_len obj.m_len;m_buf new int[m_len];for(int i 0;i m_len;i){m_buf[i] obj.m_buf[i];}return *this;}
bool NewArray::operator(NewArray obj)
{if(m_len ! obj.m_len){return false;}for(int i 0;i m_len;i){if(m_buf[i] ! obj.m_buf[i]){return false;}}return true;
}
bool NewArray::operator!(NewArray obj)
{return !((*this) obj);
}
测试文件
#include newarray.h
using namespace std;int main()
{NewArray a1(10);for (int i0; ia1.length(); i){//成员函数方式赋值a1.setData(i, i);//下标运算符重载赋值a1[i] i;//函数返回值当左值需要返回一个引用//a1.operator [i]}cout\na1: ;for (int i0; ia1.length(); i){//couta1.getData(i) ;//成员函数方式获取元素//下标运算符方式获取数组元素couta1[i]\t;}coutendl;//赋值运算符重载NewArray a2 a1;cout\na2: ;for (int i0; ia2.length(); i){couta2.getData(i) ;}coutendl;//3NewArray a3(5);{a3 a1;a3 a2 a1;cout\na3: ;for (int i0; ia3.length(); i){couta3[i] ;}}//功能4if (a3 a1){printf(\nequal\n);}else{printf(\nnot equal\n);}//a3.operator(a1);//bool operator(Array a1);if (a3 ! a1){printf(\nnot equal\n);}else{printf(\nequal\n);}////a3.operator!(a1)// bool operator!(Array a1);couthello...endl;return 1;
}
5.重载函数调用运算符
() 运算符用于函数调用重载格式
类型 类 :: operator() ( 表达式表 )
只能用成员函数重载不能用友元函数重载
例1 设 x 是类 X 的一个对象则表达式 x ( arg1, arg2, … ) 可被解释为 x . operator () (arg1, arg2, … ) 案例
例2用重载()运算符实现数学函数的抽象
#include iostream
class F{ public : double operator ( ) ( double x , double y ) ;} ;
double F :: operator ( ) ( double x , double y ){ return x * x y * y ; }
void main ( )
{
F f ;
f.getA();cout f ( 5.2 , 2.5 ) endl ; // f . operator() (5.2, 2.5)
}
例3 用重载()运算符实现 pk 成员函数
#include iostream.h
class F{ public : double memFun ( double x , double y ) ;} ;
double F :: memFun ( double x , double y ){ return x * x y * y ; }
void main ( )
{
F f ;cout f.memFun ( 5.2 , 2.5 ) endl ;
}
6.不建议重载的运算符 理论知识 1和||是C中非常特殊的操作符 2和||内置实现了短路规则 3操作符重载是靠函数重载来完成的 4操作数作为函数参数传递 5C的函数参数都会被求值无法实现短路规则 #include cstdlib
#include iostreamusing namespace std;class Test
{int i;
public:Test(int i){this-i i;}Test operator (const Test obj){Test ret(0);cout执行号重载函数endl;ret.i i obj.i;return ret;}bool operator (const Test obj){cout执行重载函数endl;return i obj.i;}
};// 从左向右
void main()
{int a1 0;int a2 1;cout注意操作符的结合顺序是从左向右endl;if( a1 (a1 a2) ){cout有一个是假则不在执行下一个表达式的计算endl;}Test t1 0;Test t2 1;//if( t1 (t1 t2) )//t1 t1.operator(t2)// t1.operator( t1.operator(t2) ) //1 || 重载他们 不会产生短路效果if( (t1 t2) t1){//t1.operator(t2) t1;//(t1.operator(t2)).operator(t1);cout两个函数都被执行了而且是先执行了endl;}//2 运算符的结合性// 两个逻辑与运算符 在一块的时候, 采去谈 运算符的结合性// 从左到右 (t1 t2) t1 ; 运算结果 t2)//if( (t1 t2) t1 t2){//t1.operator(t2) t1;//(t1.operator(t2)).operator(t1);cout两个函数都被执行了而且是先执行了endl;}system(pause);return ;
}
5.字符串类的实现
头文件
#ifndef MYSTRING_H
#define MYSTRING_H
#include iostream
using namespace std;
#include stdlib.h
#include string.h
class MyString
{
public:MyString();MyString(int _len);MyString(const char *_str);MyString(const MyString obj);~MyString();MyString operator (const MyString obj);MyString operator (const char * _str);bool operator (const MyString obj);bool operator (const char * _str);bool operator !(const MyString obj);bool operator !(const char * _str);bool operator (const MyString obj);bool operator (const char * _str);bool operator (const MyString obj);bool operator (const char * _str);char operator [](int index);friend ostream operator(ostream out,MyString obj);friend istream operator(istream in,MyString obj);private:int m_len;char *m_str;
};#endif // MYSTRING_H
实现文件
#include mystring.hMyString::MyString()
{m_len 0;m_str NULL;
}
MyString::MyString(int _len)
{if(_len 0)_len 0;m_len _len;m_str new char[m_len1];memset(m_str,0,m_len);
}MyString::MyString(const char *_str)
{if(_str NULL){m_len 0;m_str new char[m_len1];strcpy(m_str,);}else{m_len strlen(_str);m_str new char[m_len1];strcpy(m_str,_str);}}
MyString::MyString(const MyString obj)
{m_len obj.m_len;m_str new char[m_len1];strcpy(m_str,obj.m_str);
}
MyString::~MyString()
{if(m_str ! NULL){delete []m_str;m_str NULL;m_len 0;}
}MyString MyString::operator (const MyString obj)
{if(m_str ! NULL){delete []m_str;m_str NULL;m_len 0;}m_len obj.m_len;m_str new char[m_len1];strcpy(m_str,obj.m_str);return *this;
}MyString MyString::operator (const char * _str)
{if(m_str ! NULL){delete []m_str;m_str NULL;m_len 0;}if(_str NULL){m_len 0;m_str new char[m_len1];strcpy(m_str,);}else{m_len strlen(_str);m_str new char[m_len1];strcpy(m_str,_str);}return *this;
}bool MyString::operator (const MyString obj)
{if(m_len ! obj.m_len){return false;}return !strcmp(m_str,obj.m_str);}bool MyString::operator (const char * _str)
{if(_str NULL){if(m_len 0){return true;}else{return false;}}else{if(m_len strlen(_str)){return !strcmp(m_str,_str);}else{return false;}}}bool MyString::operator !(const MyString obj)
{return !((*this) obj);
}bool MyString::operator !(const char * _str)
{return !((*this) _str);
}bool MyString::operator (const MyString obj)
{if(strcmp(m_str,obj.m_str) 0){return true;}else{return false;}
}bool MyString::operator (const char * _str)
{if(strcmp(m_str,_str) 0){return true;}else{return false;}
}bool MyString::operator (const MyString obj)
{if(strcmp(m_str,obj.m_str) 0){return true;}else{return false;}
}bool MyString::operator (const char * _str)
{if(strcmp(m_str,_str) 0){return true;}else{return false;}
}char MyString::operator [](int index)
{return m_str[index];
}ostream operator(ostream out,MyString obj)
{outobj.m_str;return out;
}istream operator(istream in,MyString obj)
{inobj.m_str;return in;
}
测试文件
#define _CRT_SECURE_NO_WARNINGS#include mystring.hvoid main01()
{MyString s1;MyString s2(s2);MyString s2_2 NULL;MyString s3 s2;MyString s4 s4444444444;//测试运算符重载 和 重载[]//s4 s2;s4 s2222;s4[1] 4;printf(%c, s4[1]);couts4 endl;//ostream operator(ostream out, MyString s)//char operator[] (int index)//MyString operator(const char *p);//MyString operator(const MyString s);couthello...endl;system(pause);return ;
}void main02()
{MyString s1;MyString s2(s2);MyString s3 s2;if (s2 aa){printf(相等);}else{printf(不相等);}if (s3 s2){printf(相等);}else{printf(不相等);}}
void main03()
{MyString s1;MyString s2(s2);MyString s3 s2;s3 aaa;if (s3 bbbb ){printf(s3 小于 bbbb);}else{printf(s3 大于 bbbb);}MyString s4 aaaaffff;//strcpy(s4.c_str(), aa111); //MFCcouts4endl;
}void main011()
{MyString s1(128);cout\n请输入字符串(回车结束);cins1;couts1;system(pause);}int main()
{MyString s1(128);cout\n请输入字符串(回车结束);cins1;couts1endl;system(pause);return 0;} 总结 操作符重载是C的强大特性之一操作符重载的本质是通过函数扩展操作符的语义operator关键字是操作符重载的关键friend关键字可以对函数或类开发访问权限操作符重载遵循函数重载的规则操作符重载可以直接使用类的成员函数实现, [], ()和-操作符只能通过成员函数进行重载操作符通过一个int参数进行前置与后置的重载C中不要重载和||操作符