C++中的赋值操作符重载和拷贝构造函数
1,关于赋值的疑问:
1,什么时候需要重载赋值操作符?
2,编译器是否提供默认的赋值操作符?
2,关于赋值的疑问:
1,编译器为每个类默认重载了赋值操作符;
1,意味着同类型的类对象可以相互赋值;
2,默认的赋值操作符仅完成浅拷贝;
3,当需要进行深拷贝时必须重载赋值操作符;
1,和拷贝构造函数相同;
4,赋值操作符与拷贝构造函数有相同的存在意义;
3,默认赋值操作符重载编程实验:
1,main.cpp 文件:
#include <iostream>
#include <string> using namespace std; class Test
{
int* m_pointer;
public:
Test()
{
m_pointer = NULL;
}
Test(int i)
{
m_pointer = new int(i);
}
Test(const Test& obj)
{
m_pointer = new int(*obj.m_pointer);
}
Test& operator = (const Test& obj)
{
if( this != &obj ) // 避免自赋值;
{
delete m_pointer;
m_pointer = new int(*obj.m_pointer);
} return *this;
}
void print()
{
cout << "m_pointer = " << hex << m_pointer << endl;
}
~Test()
{
delete m_pointer;
}
}; int main()
{
Test t1 = ;
Test t2; t2 = t1; // 默认赋值操作符的浅拷贝使得两个对象内部指针指向同一片空间; int i = ; // C 语言中允许这样,所以 C++ 中也必须允许;
i = i; t2 = t2; // C++ 中也要允许自赋值,但是没有意义; t1.print();
t2.print(); return ;
}
2,输出结果:
m_pointer = 0x9387008
m_pointer = 0x9387018
3,赋值操作符重载注意事项:
1,赋值操作符返回值一定是引用,为了连续赋值;
2,参数类型一定是 const Type&;
3,不能自赋值;
4,返回当前对象;
4,关于赋值的疑问:

1,如果要进行深拷贝,拷贝构造函数和赋值操作符的实现都要自定义;
5,一般性原则:
1,重载赋值操作符,必然要实现深拷贝;
1,实现深拷贝和自定义赋值操作符及拷贝构造函数是充要条件;
6,数组类的优化编程实验:
1,IntArray.h 文件:
#ifndef _INTARRAY_H_
#define _INTARRAY_H_ class IntArray
{
private:
int m_length;
int* m_pointer; IntArray(int len);
IntArray(const IntArray& obj);
bool construct();
public:
static IntArray* NewInstance(int length);
int length();
bool get(int index, int& value);
bool set(int index ,int value);
int& operator [] (int index);
IntArray& operator = (const IntArray& obj);
IntArray& self();
~IntArray();
};
2,首先写出赋值操作符注意事项模板:
IntArray& IntArray::operator = (cosnt IntArray& obj)
{
if( this != &obj )
{ } return *this;
}
3,函数实现:
IntArray& IntArray::operator = (const IntArray& obj)
{
if( this != &obj )
{
int* pointer = new int[obj.m_length]; if( pointer )
{
/* 复制参数对象中的元素 */
for(int i=; i<obj.m_length; i++)
{
pointer[i] = obj.m_pointer[i];
} /* 深拷贝 */
m_length = obj.m_length;
delete[] m_pointer;
m_pointer = pointer;
}
} return *this;
}
4,main.cpp 文件:
#include <iostream>
#include <string>
#include "IntArray.h" using namespace std; int main()
{
IntArray* a = IntArray::NewInstance();
IntArray* b = IntArray::NewInstance(); if( a && b )
{
IntArray& array = a->self();
IntArray& brray = b->self(); cout << "array.length() = " << array.length() << endl;
cout << "brray.length() = " << brray.length() << endl; array = brray; cout << "array.length() = " << array.length() << endl;
cout << "brray.length() = " << brray.length() << endl;
} delete a;
delete b; return ;
}
5,输出结果:
array.length() =
brray.length() =
array.length() =
brray.length() =
6,使用二阶构造后,拷贝构造函数是私有的,拷贝构造函数就没有作用了,不允许拷贝构造,但是应该重载赋值操作符重载;
7,编译器默认提供函数:

1,虽然类中什么都没写,但是编译器会放四个函数实现进去;
8,下面的代码输出什么?为什么?
1,代码示例:
string s = "";
const char* p = s.c_str(); // 返回字符指针,代表 C 语言中的字符串; cout << p << endl; s.append("abced"); cout << p << endl;
9,字符串问题 1 编程实验:
1,main.cpp 文件:
#include <iostream>
#include <string> using namespace std; int main()
{
string s = "";
const char* p = s.c_str(); // 只有这一行用了 C 方式; cout << p << endl; s.append("abced"); // p 成为了野指针 cout << p << endl; return ;
}
2,这段代码混合了 C 和 C++ 的方式,出了意想不到的错误;
10,关于 string 的疑问 1:

1,string 对象内部维护了一个指向数据的 char* 指针,这个指针可能在程序 运行的过程中发生改变,我们尽量不要操作这个指针;
2,执行 s.append() 函数后,char* 指针指向了新的堆空间 0xFF445566,而将旧的堆空间 0xFF112233 释放,此时 p 指针成了野指针;
3,学习 C++,并且用的是标准库中的内容,所以现在采用的编程思想就应该是 C++ 编程思想,不要混合使用 C 和 C++ 思想;
11,下面的程序输出什么?为什么?
1,代码示例:
const char* p = ""; // p 可以用字符串对象代替;
string s = ""; // 混合了,该注意了; s.reserve(); // 不要使用 C 语言中的方式操作 C++ 中的字符串
for(int i=; i<; i++)
{
s[i] = p[i];
} if( !s.empty() )
{
cout << s << endl;
}
2,没有输出;
12,字符串问题 2 编程实验:
1,main.cpp 文件:
#include <iostream>
#include <string> using namespace std; int main()
{
const char* p = "";
string s = ""; s.reserve(); // 不要使用 C 语言中的方式操作 C++ 中的字符串
for(int i=; i<; i++)
{
s[i] = p[i];
} if( !s.empty() ) // 打印不出;
{
cout << s << endl;
} cout << s << endl; // 打印不出; for(int i=; i<; i++) // 可以打印;
{
cout << s[i] << endl;
} return ;
}
2,更改程序为:
#include <iostream>
#include <string> using namespace std; int main()
{
const string p = "";
string s = ""; s = p; cout << s << endl; return ;
}
3,C++ 工程中,尽量避免指针使用,字符串类出现就是为了替代字符指针;
13,关于 string 的疑问 2:

14,小结:
1,在需要进行深拷贝的时候必须重载赋值操作符;
1,也要重新定义拷贝构造函数;
2,赋值操作符和拷贝构造函数有同等重要的意义;
3,string 类通过一个数据空间保存字符串数据;
4,string 类通过一个成员变量保存当前字符串的长度;
5,C++ 开发时尽量避开 C 语言中惯用的编程思想;
1,字符串类得到的是字符串对象,直接用成员函数操作这个对象就可以,不需要用 C 语言中的 for 循环之类的;
C++中的赋值操作符重载和拷贝构造函数的更多相关文章
- 析构函数-复制构造函数-赋值操作符重载-默认构造函数<代码解析>
通过下面primer中的一道习题,可以更深刻的了解,析构函数,复制构造函数,赋值操作符重载,默认构造函数的使用. 但是我的结果与primer习题解答里面的并不相同,可能是编译器不同的原因导致. // ...
- C#中如何利用操作符重载和转换操作符
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C#中如何利用操作符重载和转换操作符 (转载)
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C++中的数组操作符重载
1,本文讲述数组操作符重载,上篇博文的字符串类 string 确实强大,但 string 类 对象还具备 C 方式字符串的灵活性吗?还能直接访问单个字符吗? 1,C 方式字符串灵活性是指能够通过数组 ...
- C++与java中的赋值操作符
#include <iostream> using namespace std; class BankAccount{ private: double balance; public: B ...
- python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域
http://my.oschina.net/leejun2005/blog/145911 http://www.cnblogs.com/lulipro/p/5060163.html http://ww ...
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- C++ 拷贝构造函数和赋值构造函数
转自:http://blog.chinaunix.net/uid-28662931-id-3496326.html 一.拷贝构造函数 int main(int argc, char * argv[]) ...
- C++构造函数详解(复制构造函数 也是 拷贝构造函数)
构造函数是干什么的 该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作,故:构造函数的作用:初始化对象的数据成员. 构造函数的种类 1 class Com ...
随机推荐
- jQuery2.0.3源码
概览 整体结构 (function (){ (21 , 94) 定义了一些变量和函数 jQuery=function(); (96 , 293) 给jQuery对象添加一些方法和属性; (285 ...
- vue 设置 input 为不可以编辑
我用最笨的方法,先实现功能先,用两个input,一个可以编辑,一个不可以编辑,失去焦点后隐藏可以点击的那个,点"编辑"时,显示可以编辑的那个input <div class= ...
- 如何导出不带.svn的文件夹
在工作环境中,有的时候需要将本地SVN服务器中的文件导出来,提交到另一个SVN服务器中去(比如做现场开发时,由于外网速度慢,项目组内部往往使用一个SVN服务器,但又同时又需要公司统一管理,定期提交到公 ...
- python1--比较三个数值的大小
num1 = input("num1:")num2 = input("num2:")num3 = input("num3:")num = m ...
- 使用 CSS 显示 XML
通过使用 CSS,可为 XML 文档添加显示信息. 使用 CSS 显示您的 XML? 使用 CSS 来格式化 XML 文档是有可能的. 下面的例子就是关于如何使用 CSS 样式表来格式化 XML 文档 ...
- MYSQL安装失败,一打开就出现MySQL-Workbench已停止工作
1.由于系统重新安装,环境都是新的,出现MySQL-Workbench已停止工作 解决:下载 微软常用运行库合集 安装即可
- Shell中Bash的基本功能(二)
1 历史命令 1)历史命令的查看[root@localhost ~]# history [选项] [历史命令保存文件]选项:-c: 清空历史命令-w: 把缓存中的历史命令写入历史命令保存文件.如果不手 ...
- CodeForces 1200E Compress Words
\(C_n^m\)的typora,点了一下启用源代码模式就把我已经写好的博客弄没了,就给我留个标题,自动保存也只给我保存了个标题--\(C_n^m\),wdnmd Time limit 1000 ms ...
- Android字体设置,Roboto字体使用
一.自定义字体 1.android Typeface使用TTF字体文件设置字体 我们可以在程序中放入ttf字体文件,在程序中使用Typeface设置字体.第一步,在assets目录下新建fonts目录 ...
- (65)CRC32校验C语言版本
#include<iostream> # include <stdio.h> # include <string.h> typedef unsigned int u ...