CArray a2(a1);
如果使用系统默认的复制构造函数,只会复制成员变量
a2.ptr = a1.ptr 浅拷贝 内存垃圾
赋值号 = 需要重载 浅拷贝 深拷贝
#include<iostream> using namespace std; class CArray { int size; //数组元素的个数 int* ptr; //指向动态分配的数组 public: CArray(int s = 0); //s代表数组元素的个数 CArray(CArray &a); // copy constructor ~CArray(); void push_back(int v);//用于在数组尾部添加一个元素v CArray & operator=(const CArray& a);//用于数组对象间的赋值 int length() { return size; } int & CArray::operator[](int i) { return ptr[i]; } }; CArray::CArray(int s) :size(s) { if (s == 0) ptr = NULL; else ptr = new int[s]; } CArray::CArray(CArray & a) { if (!a.ptr) { ptr = NULL; size = 0; return; } ptr = new int[a.size]; memcpy(ptr, a.ptr, sizeof(int) * a.size); size = a.size; } CArray::~CArray() { if (ptr) delete[] ptr; } CArray& CArray::operator= (const CArray& a) { if (ptr == a.ptr) return *this; if (a.ptr == NULL) // 如果a里面的数组是空的 { if (ptr) delete[] ptr; ptr = NULL; size = 0; return *this; } if (size < a.size)//如果原有空间够大,就不用分配新的空间 { if (ptr) delete[] ptr; ptr = new int[a.size]; } memcpy(ptr, a.ptr, sizeof(int)*a.size); size = a.size; return *this; } // CArray & CArray::operator=(const CArray & a) void CArray::push_back(int v) {//在数组尾部添加一个元素 if (ptr) { int *tmpPtr = new int[size + 1];//重新分配空间 memcpy(tmpPtr, ptr, sizeof(int)*size);//拷贝原数组内容 delete[] ptr; ptr = tmpPtr; } else ptr = new int[1]; ptr[size++] = v; // 加入新的数组元素 } int main()//要编写可变长整型数组类,使之能如下使用: { CArray a; for (int i = 0; i < 5; ++i) a.push_back(i); CArray a2, a3; a2 = a; for (int i = 0; i < a.length(); ++i) cout << a2[i] << " "; a2 = a3; for (int i = 0; i < a2.length(); ++i) cout << a2[i] << " "; cout << endl; a[3] = 100; CArray a4(a); for (int i = 0; i < a4.length(); ++i) cout << a4[i] << " "; while (1); return 0; }
流插入运算符和流提取运算符的重载
#if 0 #include<iostream> using namespace std; /*假定下面程序输出为 5hello, 该补写些什么*/ class CStudent { public: int nAge; }; ostream& operator<<(ostream & o, const CStudent & s) { o << s.nAge; return o; } int main() { CStudent s; s.nAge = 5; cout <<s << "hello"; while (1); return 0; } #endif /*假定c是Complex复数类的对象,现在希望写“cout << c;”, 就能以“a+bi”的形式输出c的值,写“cin>>c;”, 就能从键盘接受“a+bi”形式的输入, 并且使得c.real = a,c.imag = b*/ #include<iostream> #include<string> #include<cstdlib> using namespace std; class Complex { double real, imag; public: Complex(double r = 0, double i = 0) :real(r), imag(i) {}; friend ostream & operator<<(ostream & os, const Complex & c); friend istream & operator>>(istream & is, Complex & c); }; ostream& operator<<(ostream&os, const Complex &c) { os << c.real << "+" << c.imag << "i"; return os; } istream & operator>>(istream & is, Complex & c) { string s; is >> s; int pos = s.find("+", 0); string sTmp = s.substr(0, pos); c.real = atof(sTmp.c_str()); sTmp = s.substr(pos + 1, s.length() - pos - 2); c.imag = atof(sTmp.c_str()); return is; } /* 13.2+133i 87↙ 13.2+133i, 87 */ int main() { Complex c; int n; cin >> c >> n; cout << c << "," << n; while (1); return 0; }
自加/自减运算符的重载
自加++/自减--运算符有前置/后置之分
前置运算符作为一元运算符重载
重载为成员函数:
T &operator++();
T &operator--();
重载为全局函数:
T &operator++(T &);
T &operator—(T &);
++obj, obj.operator++(), operator++(obj) 都调用上述函数
后置运算符作为二元运算符重载
多写一个参数, 具体无意义
•重载为成员函数:
T operator++(int);
T operator--(int);
•重载为全局函数:
T operator++(T &, int);
T operator--(T &, int);
obj++, obj.operator++(0), operator++(obj,0) 都调用上函数
operator int( ) { return n; }
int作为一个类型强制转换运算符被重载,
Demo s;
(int) s ; //等效于s.int();
类型强制转换运算符重载时,
•不能写返回值类型
•实际上其返回值类型--类型强制转换运算符代表的类型
运算符重载的注意事项
C++不允许定义新的运算符
重载后运算符的含义应该符合日常习惯
•complex_a+ complex_b
•word_a> word_b
•date_b= date_a+ n
运算符重载不改变运算符的优先级
以下运算符不能被重载: “.”, “.*”, “::”, “?:”, sizeof
重载运算符(), [ ], ->或者赋值运算符=时, 重载函数必须声明为类的成员函数
#include<iostream> using namespace std; class CDemo { private: int n; public: CDemo(int i = 0) :n(i) {} CDemo & operator++(); //用于前置++形式 CDemo operator++(int); //用于后置++形式 //int作为一个类型强制转换运算符被重载, operator int() { return n; } // 强制类型转换,没有返回值 friend CDemo & operator--(CDemo &); //用于前置--形式 friend CDemo operator--(CDemo&, int); //用于后置--形式 }; CDemo & CDemo::operator++() { n++; return *this; } CDemo CDemo::operator++(int k)//后置++ { CDemo tmp(*this);//记录修改前的对象 n++; return tmp; // 返回修改前的对象 } CDemo & operator--(CDemo & d) { d.n--; return d; } CDemo operator--(CDemo & d, int) { CDemo tmp(d); d.n--; return tmp; } int main() { CDemo d(5); cout << (d++) << ","; cout << d << ","; cout << ++d << ","; cout << d << endl; cout << (d--) << ","; cout << d << ","; cout << --d << ","; cout << d << endl; while (1); return 0; }