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 ...
随机推荐
- Mac OS找不到/usr/include文件夹的解决办法
Mojave最新解决方案:终端执行: xcode-select --install #完成后执行 sudo installer -pkg /Library/Developer/CommandLineT ...
- vue作业2
""" 2.现有以下成绩单数据 scores = [ { name: 'Bob', math: 97, chinese: 89, english: 67 }, { nam ...
- GO语言学习笔记4-int与string类型转换
int与string类型之间相互转换可以借助strconv包里自带的函数实现. 1.string转换成int 函数原型: // base指定进制(2到36),如果base为0,则会从字符串前置判断, ...
- PHP基础教程探讨一些php编程性能优化总结
兄弟连PHP培训 小编最近在做php程序的性能优化,一些经过测试后发现的东西就先记录下来,以备后用. 首先对于一些反应慢的操作或页面要跟踪处理一下,可以使用webGrind的方式看一下主要问题出在 ...
- BZOJ 3786: 星系探索 ETT
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- #419 Div2 Problem B Karen and Coffee (统计区间重叠部分 && 前缀和)
题目链接 :http://codeforces.com/contest/816/problem/B 题意 :给出 n 表示区间个数,限定值 k 以及问询次数 q,当一个数被大于或等于 k 个区间重复覆 ...
- 【canvas学习笔记七】混合和裁剪
globalCompositeOperation 如果我们先画了一个图形,然后要在这个图形上面再画一个图形,那么这个图形会怎么样呢?是覆盖在原来的图形上面吗?这时候,就要用到globalComposi ...
- Http请求详解(转)----请求+响应各字段详解
参考HTTP深入浅出http请求(转)-----http请求的过程和实现机制 1. HTTP请求格式 首先介绍HTTP协议:超文本传输协议(HTTP,HyperText Transfer Protoc ...
- centos网卡配置NM_CONTROLLED=”yes” 慎用
今天有1台服务器修改了 /etc/sysconfig/network-scripts/ifcfg-eth0 配置文件中的一个参数: NM_CONTROLLED=“yes” 修改成 NM_CONTROL ...
- android intent调用系统camera
利用android的camera通常有两种方式:利用intent调用系统的camera,或者结合surfaceview实现自己定制的camera.先分别对这两种方法说明如下: 一.使用系统自配的cam ...