剑指Offer算法实现之一:赋值运算符函数
来源:互联网 发布:nba中国官方软件 编辑:程序博客网 时间:2024/06/01 23:52
题目:如下为类型CMyString的声明,请为该类型添加运算符函数
class CMyString{public: CMyString(char *pData = NULL); CMyString(const CMyString& str); ~CMyString();private: char *m_pData;};
思路:考虑下列问题:
1. 返回自身的引用
2. 处理“自我赋值”
3. 异常安全性
编译环境:ArchLinux+Clang3.3, X86_64
实现一:
现在临时字符数组上作拷贝,然后与对象的数据成员交换,最后将多余的数组释放。关键代码如下:
CMyString& CMyString::operator=(const CMyString& oth){ if (this == &oth) return *this; // 此句即使略去,自我赋值也不会带来错误,自我复制几率极小,因此不会带来性能问题 char *tmp = new char[strlen(oth.m_pData)+1]; // 创建临时字符数组 strcpy(tmp, oth.m_pData); swap(m_pData, tmp); // 交换指针,标准库函数 delete[] tmp; // 释放原对象的数据 return *this;}
实现二:
使用copy-swap技术,解决实现一代码冗余的问题。这样,实现一中临时对象释放问题就可交由CMyString的析构对象负责,并且可充分利用copy构造函数。关键代码如下:
CMyString& CMyString::operator=(const CMyString& oth){ CMyString strTmp{oth}; // copy swap(this->m_pData, strTmp.m_pData); // swap(标准库函数) return *this;}
实现三:
实现二提高了代码复用。也可以使用C++11的move操作符函数和右值引用达到同样的效果。尽管多提供了一个move操作符函数,但对于CMyString这样持有潜在大量动态内存的类来说,不仅可以供编译器优化,而且还可手动调用,这是值得的。
CMyString& CMyString::operator=(CMyString&& oth){ swap(this->m_pData, oth.m_pData); //做了一个swap,this持有的动态内存由oth的析构函数释放 return *this;}CMyString& CMyString::operator=(const CMyString& oth){ CMyString strTmp{oth}; *this = move(strTmp); // 右值引用语义 return *this;}完整代码:
#include <iostream>#include <cstring>using namespace std;class CMyString{public: CMyString(const char *pData = nullptr); CMyString(const CMyString& str); CMyString& operator=(const CMyString& oth); CMyString& operator=(CMyString&& oth); ~CMyString(); friend ostream& operator<<(ostream& out, CMyString& str);private: char *m_pData;};CMyString::CMyString(const char *pData){ if (pData == nullptr){ m_pData = nullptr; return; } m_pData = new char[strlen(pData)+1]; strcpy(m_pData, pData);}CMyString::CMyString(const CMyString& str){ m_pData = new char[strlen(str.m_pData)+1]; strcpy(m_pData, str.m_pData);}CMyString::~CMyString(){ if (m_pData != nullptr) { delete[] m_pData; }}ostream& operator<<(ostream& out, CMyString& str){ return out << str.m_pData;}/* * 实现一CMyString& CMyString::operator=(const CMyString& oth){ if (this == &oth) return *this; // 此句即使略去,自我赋值也不会带来问题 char *tmp = new char[strlen(oth.m_pData)+1]; strcpy(tmp, oth.m_pData); swap(m_pData, tmp); delete[] tmp; return *this;}*//* 实现二CMyString& CMyString::operator=(const CMyString& oth){ CMyString strTmp{oth}; swap(this->m_pData, strTmp.m_pData); return *this;}*//* 实现三 */CMyString& CMyString::operator=(CMyString&& oth){ swap(this->m_pData, oth.m_pData); return *this;}CMyString& CMyString::operator=(const CMyString& oth){ CMyString strTmp{oth}; *this = move(strTmp); return *this;}// 测试驱动int main(){ CMyString s{"hello"}; CMyString t; cout << (t = s) << endl;}
- 剑指Offer算法实现之一:赋值运算符函数
- 【剑指offer】赋值运算符函数_01
- 【剑指Offer】赋值运算符函数
- 【剑指offer】1.赋值运算符函数
- 剑指offer - 赋值运算符函数
- 《剑指offer》01 赋值运算符函数
- 剑指offer--赋值运算符函数
- 剑指offer-01:赋值运算符函数
- [互联网面试笔试汇总C/C++-9] 实现赋值运算符函数-剑指offer
- 剑指offer 赋值运算符
- 剑指Offer:面试题01---赋值运算符函数
- 剑指offer面试题(一):赋值运算符函数
- 剑指offer:面试题一:赋值运算符函数
- 《剑指Offer》面试题1:赋值运算符函数
- 剑指Offer系列---(3)赋值运算符函数
- 剑指offer:面试题1 赋值运算符函数
- 剑指offer,面试题一:赋值运算符函数
- 《剑指offer》——重载赋值运算符函数
- 【百WA然后AC】HDU 1728——逃离迷宫
- letter and number
- POJ 2479
- Storm集群部署
- java继承 初始化顺序
- 剑指Offer算法实现之一:赋值运算符函数
- Web service是什么?
- QT信号和槽机制注意事项
- 使用js弹出模态窗口,提交保存数据后关闭模态窗口,刷新父窗口
- 设置环境变量
- CreateEvent用法
- EditPlus正则表达式实例
- 各品牌手机进rec快捷键
- PHP底层的运行机制与原理