String类的四个默认成员函数
优化版的拷贝构造函数,先创建一个暂时实例tmp,接着把tmp._ptr和this->_ptr交换,因为tmp是一个局部变量。程序执行到该函数作用域外,就会自己主动调用析构函数。释放tmp._ptr所指向的内存。
因为交换之后tmp._ptr指向实例之前_ptr的内存。_ptr一定要赋初值为NULL,否则析构一个随机值就会崩溃。我们在String的构造函数里用new分配内存,假设因为内存不足抛出诸如bad_alloc等异常。我们还没有改动原来的实例状态,保证了异常的安全性。
#include<iostream>
#include<string>
#pragma warning (disable:4996)
using namespace std;
class String
{
public:
String(char *p) :_ptr(new char[strlen(p) + 1])
{
if (_ptr != 0)
{
strcpy(_ptr, p);
}
}
void swap(String &s)
{
char* tmp = s._ptr;
s._ptr = _ptr;
_ptr = tmp;
}
//优化版
String(const String &s) :_ptr(NULL) //_ptr要置为NULL,否则释放一块随机值会出错
{
String tmp(s._ptr);
swap(tmp);
}
/*String& operator= (const String &s)
{
if (this != &s)
{
String tmp(s._ptr);
swap(tmp);
}
return *this;
}*/
//最优版
String& operator= (String s)
{
swap(s);
return *this;
}
//原始版本号
/*String(const String &s)
{
_ptr = new char[strlen(s._ptr) + 1];
if (_ptr != 0)
{
strcpy(_ptr, s._ptr);
}
}
String& operator= (const String &s)
{
if (this != &s)
{
delete _ptr;
_ptr = new char[strlen(s._ptr) + 1];
if (_ptr != 0)
{
strcpy(_ptr, s._ptr);
}
}
return *this;
}*/
~String()
{
if (_ptr)
{
delete[] _ptr;
}
}
void Display()
{
cout << _ptr << endl;
}
private:
char *_ptr;
};
int main()
{
String s1("yangrujing"), s2("yangfeipan");
String s3(s1);
s3.Display();
s1 = s2;
s1.Display();
getchar();
return 0;
}String类的四个默认成员函数的更多相关文章
- C++默认成员函数
1.什么是面向对象? 概念:(Object Oriented Programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法. 对象指的是类的实例,将对象作为程序的基本单元,将程 ...
- C++中的默认成员函数
一般而言,对于一个用户自定义的类类型,以下四个函数在用户没有自定义的情形下,会由编译器自动生成: 1.default constructor 2.copy constructor Someclass: ...
- 类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)
假设我们要设计一个包含以下操作的 Sales_data 类: 1.一个 isbn 成员函数,用于返回对象的 book_no 成员变量 2.一个 combine 成员函数,用于将一个 Sales_dat ...
- 如何禁止C++默认成员函数
如何禁止C++默认成员函数 发表于 2016-03-02 | 分类于 C++ | 阅读次数 17 前言 前几天在一次笔试过程中被问到C++如何设计禁止调用默认构造函数,当时简单的想法是直 ...
- vc MFC 通过IDispatch调用默认成员函数
CComPtr<IDispatch> spDisp(IDispatch *); if(!spDisp) return; DISPPARAMS dispParam={0}; //没有参数 V ...
- C++中的类继承(2)派生类的默认成员函数
在继承关系里面, 在派生类中如果没有显示定义这六个成员 函数, 编译系统则会默认合成这六个默认的成员函数. 构造函数. 调用关系先看一段代码: class Base { public : Base() ...
- C++类的默认成员函数
成员函数隐含this指针参数: 每成员函数一个隐式的指针形参(构造函数除外): 对象在调用成员函数时,编译器会将对象的地址传递给this指针: 1.构造函数(需用一个公有成员函数对私有的成员变量进行初 ...
- C#中Stack<T>类的使用及部分成员函数的源代码分析
Stack<T>类 Stack<T> 作为数组来实现. Stack<T> 的容量是 Stack<T> 能够包括的元素数. 当向 Stack<T&g ...
- 类中用const限定的成员函数
本文转自http://blog.csdn.net/whyglinux/article/details/602329 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非 ...
随机推荐
- 简单说一下 TCP打洞和UDP打洞
1, TCP协议通信: 现在有两台电脑A和B.在 假设A的地址为 192.168.0.100 假设B的地址为 192.168.0.102 A想给B发送一个字符串Hello, 如果A,B之间采用TCP ...
- 获取select标签选中的值的三种方式
var obj = document.getElementByIdx_x(”testSelect”); //定位id var index = obj.selectedIndex; // 选中索引 va ...
- org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [********] will not be managed by Spring
如下图,查看层次是否正确.
- 08C++函数
函数 4.1 概述 一个较大的程序不可能完全由一个人从头至尾地完成,更不可能把所有的内容都放在一个主函数中.为了便于规划.组织.编程和调试,一般的做法是把一个大的程序划分为若干个程序模块(即程序文件) ...
- redis简介以及安装
redis作为开源的高性能的键值对数据库,本身是单线程的,性能虽然没有memcache高,但是也是性能跟memcache相差无几的,memcache是多线程的,但是redis本身功能更加强大,学习一下 ...
- 【2019 1月集训 Day1】回文的后缀
题意: 给定 n,s,求有多少个字符集大小为 s ,长度为 n 的字符串,使得其不存在一个长度大于 1 的回文后缀. 答案对 m 取模. 分析: 考场见到计数题的链式反应,想写暴力—>暴力难写— ...
- sql分组和连接
SELECT mr.member_id, mr.username, GROUP_CONCAT(DISTINCT jb.company,jb.start_time,jb.end_time)company ...
- SpringBoot 全局处理以及注入请求参数
后端接口,经常会用token获取对应的账号信息.于是考虑将这个步骤封装起来. 之前项目使用ThreadLocal去做这样的事情,但昨天看SpringBoot的官方文档,发现借助框架的功能也可以做这样的 ...
- day21 05 员工信息表
day21 05 员工信息表 假设有一个员工信息表,里面有每个员工的名字,id,年龄,电话,还有他们所作的工作,而有时候我们并不需要所有的信息,而想根据某些条件,寻找符合条件即可,即筛选, 比如想要筛 ...
- Python 字典(2)
一.遍历字典 一个字典可能会包含多个键-值对,字典可以以多种方式存储信息,因此有多种遍历字典的方式,比如键-值对.键.值. 1.遍历所有的键-值对 user_01 = {'username':'tiz ...