c++ 程序设计 week4 运算符重载
2016-01-17 08:13
627 查看
运算符重载
这一周的内容主要讲运算符重载, 但是如何设计返回值类型,以及是否需要采用成员函数都是很重要的。
1. 赋值运算符重载
T & operator=(T &a);
与copy constructor类类似, 但是存在返回值.
(1) 成员函数:只能定义成成员函数。
(2)返回值:而且返回值类型必须是引用,才能符合我们对等号的直观理解。(a = b) = c 还会将a改变, 所以我们需要返回T&。
(3)类内存在指针时需要注意如果右边赋值和本身相同时,不需要重新赋值; 而且如果原来为空指针,那么也可以直接赋值, 以上两种类型都需要先判断,以防delete时出现错误.
2. 运算符重载位友元函数
T operator+(const T &a, const T &b)
如果我们把函数重载为外部函数, 那么在内部设置为友元函数可以访问成员的私有member.
3. 流输入,输出函数
输出:
ostream & operator<< (ostream &os, const T & a);
(1)返回类型: &ostream, (保证流的一致性)
(2)外部重载函数, 因为我们需要 ostream << , 如果设置为内部函数则无法调用.
输入函数类似.
4. ++ ,--
前置++T: T operator++()
后置T++: T operator++(int)
所以下面用了国外一门课的例子.
例子MyString
这一周的内容主要讲运算符重载, 但是如何设计返回值类型,以及是否需要采用成员函数都是很重要的。
1. 赋值运算符重载
T & operator=(T &a);
与copy constructor类类似, 但是存在返回值.
(1) 成员函数:只能定义成成员函数。
(2)返回值:而且返回值类型必须是引用,才能符合我们对等号的直观理解。(a = b) = c 还会将a改变, 所以我们需要返回T&。
(3)类内存在指针时需要注意如果右边赋值和本身相同时,不需要重新赋值; 而且如果原来为空指针,那么也可以直接赋值, 以上两种类型都需要先判断,以防delete时出现错误.
2. 运算符重载位友元函数
T operator+(const T &a, const T &b)
如果我们把函数重载为外部函数, 那么在内部设置为友元函数可以访问成员的私有member.
3. 流输入,输出函数
输出:
ostream & operator<< (ostream &os, const T & a);
(1)返回类型: &ostream, (保证流的一致性)
(2)外部重载函数, 因为我们需要 ostream << , 如果设置为内部函数则无法调用.
输入函数类似.
4. ++ ,--
前置++T: T operator++()
后置T++: T operator++(int)
所以下面用了国外一门课的例子.
例子MyString
#MyString.h
#ifndef __MYSTRING_H__ #define __MYSTRING_H__ #include <iostream> using namespace std; class MyString { public: // default constructor MyString(); // constructor MyString(const char* p); // destructor ~MyString(); // copy constructor MyString(const MyString& s); // copy assignment MyString& operator=(const MyString& s); // returns the length of the string int length() const { return len; } friend int operator==(const MyString& s1,const MyString& s2); friend int operator!=(const MyString& s1,const MyString& s2); friend int operator>(const MyString& s1,const MyString& s2); friend int operator<(const MyString& s1,const MyString& s2); friend int operator>=(const MyString& s1,const MyString& s2); friend int operator<=(const MyString& s1,const MyString& s2); MyString& operator+=(const MyString &s); // put-to operator friend ostream& operator<<(ostream& os, const MyString& s); // get-from operator friend istream& operator>>(istream& is, MyString& s); // operator[] char& operator[](int i); // operator[] const const char& operator[](int i) const; private: char* data; int len; }; MyString operator+(const MyString& s1, const MyString& s2); #endif
#MyString.cpp
#include <cstring> #include <cstdio> #include "mystring.h" // default constructor MyString::MyString() { data = new char[1]; data[0] = '\0'; len = 0; } // constructor MyString::MyString(const char* p) { if (p) { len = strlen(p); data = new char[len+1]; strcpy(data, p); } else { data = new char[1]; data[0] = '\0'; len = 0; } } // destructor MyString::~MyString() { delete[] data; } // copy constructor MyString::MyString(const MyString& s) { len = s.len; data = new char[len+1]; strcpy(data, s.data); } // copy assignment MyString& MyString::operator=(const MyString& rhs) { #ifdef BASIC4TRACE fprintf(stderr, "BASIC4TRACE: (%p)->op=(const MyString&)\n", this); #endif if (this == rhs) { return *this; } // first, deallocate memory that 'this' used to hold delete[] data; // now copy from rhs len = rhs.len; data = new char[len+1]; strcpy(data, rhs.data); return *this; } //+=operator MyString& MyString::operator+=(const MyString &s) { len = len + s.len; char *temp = new char[len+1]; strcpy(temp,data); strcat(temp,s.data); delete[] data; data = temp; return *this; } // operator+ MyString operator+(const MyString& s1, const MyString& s2) { #ifdef BASIC4TRACE fprintf(stderr, "BASIC4TRACE: op+(const MyString&, const MyString&)\n"); #endif MyString temp = s1; temp += s2; return temp; } // put-to operator ostream& operator<<(ostream& os, const MyString& s) { os << s.data; return os; } // get-from operator istream& operator>>(istream& is, MyString& s) { // this is kinda cheating, but this is just to illustrate how this // function can work. string temp; is >> temp; delete[] s.data; s.len = strlen(temp.c_str()); s.data = new char[s.len+1]; strcpy(s.data, temp.c_str()); return is; } // operator[] - in real life this function should be declared inline char& MyString::operator[](int i) { return data[i]; } // operator[] const - in real life this should be inline const char& MyString::operator[](int i) const { // illustration of casting away constness return ((MyString&)*this)[i]; } int operator==(const MyString& s1,const MyString& s2) { return (strcmp(s1.data,s2.data)==0); } int operator!=(const MyString& s1, const MyString& s2) { return (strcmp(s1.data,s2.data)!=0); } int operator<(const MyString& s1,const MyString& s2) { return (strcmp(s1.data,s2.data)<0); } int operator>(const MyString& s1,const MyString& s2) { return(strcmp(s1.data,s2.data)>0); } int operator<=(const MyString& s1,const MyString& s2) { return(strcmp(s1.data,s2.data)<=0); } int operator>=(const MyString& s1,const MyString& s2) { return(strcmp(s1.data,s2.data)>=0); }
相关文章推荐
- Sicily 13476. 完数问题
- C++虚函数实现机制
- 学习C语言之前的准备工作
- Odd Even Linked List leetcode 328
- c++ 经验总结
- for_each算法和transform算法区别
- C语言基本内容(二)
- c++经典开发源码
- 【c++】智能指针
- C++中的内存分配
- vc++实现avi文件的操作
- 蓝桥杯 c++_ch02_01
- temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1)
- Sicily 12986. An Odd Sum
- 【LeetCode-263】Ugly Number(C++)
- AES加密 C++调用Crypto++加密库 样例
- 一起talk C栗子吧(第一百零四回:C语言实例--进程知识体系图)P:一图看懂进程
- eclipse下使用C++开发opencv的android程序
- LeecCode 17
- Problem H: C语言实验——求阶乘(循环结构)