头文件 DString.h如下

#ifndef __DSTRING_H
#define __DSTRING_H
#endif #include <stddef.h> class DString
{
public:
DString(const char * c = NULL); // default constructor
DString(const DString &str); // copy constructor - implement DEEP copy ~DString(); /*
必须使用成员函数重载的运算符 = ( ) [ ] ->
必须使用友元函数重载的运算符 << >>
P.S. 一目运算符,建议使用成员函数;二目运算符,建议只用友元函数
*/
DString& operator = (const DString &str);
friend DString operator + (const DString &s1, const DString &s2);
char* dcopy(char * dst, const char * src); private:
char * m_data;
};

实现如下DString.cpp

#include <string.h>

#include "DString.h"

DString::DString(const char * c)
{
if(NULL == c)
{
m_data = new char('\0');
}
else
{
m_data=new char[strlen(c) + ];
dcopy(m_data, c);
}
} DString::DString(const DString &str)
{
if(NULL== str.m_data)
{
m_data=NULL;
}
else
{
m_data=new char[strlen(str.m_data) + ];
dcopy(m_data, str.m_data);
}
} DString::~DString()
{
delete [] m_data;
} DString& DString::operator = (const DString &str)
{
if(this == &str) // the same one
{
return *this;
}
else
{
delete [] m_data;
m_data=new char[strlen(str.m_data)+];
dcopy(m_data,str.m_data);
return *this;
}
} // no :: because friend function doesnt belong to the class
DString operator + (const DString &s1, const DString &s2)
{
if(NULL == s1.m_data)
{
return DString(s2);
} if(NULL == s2.m_data)
{
return DString(s1);
} char * temp = new char[strlen(s1.m_data) + strlen(s2.m_data) + ];
strcpy(temp, s1.m_data);
strcpy(temp+strlen(s1.m_data), s2.m_data); return DString(temp);
} char* DString::dcopy(char * dst, const char * src)
{
char * tmp = dst; while(*src != '\0')
{
*tmp++ = *src++;
} *tmp = ; return dst;
}

DString.cpp

调用入口main.cpp

#include "DString.h"

int main(int argc, char* argv[])
{
DString s1("abcde"); //call default cons
DString s2 = "ABC"; //call default cons DString s3 = s2; //call copy cons
DString s4(s3); //call copy cons s1 = s4; //call operator = s4 = s1 + s2 + "ding"; //call default cons then + then + then =
return ;
}

一些知识点(以在代码中出现的顺序排列)

  1. 对于一个空的类,默认会有6个成员函数:构造/析构/拷贝构造/赋值/const取址/非const取址
  2. 在函数声明时使用了默认参数,则在实现时就不能再次指定默认参数
  3. 对于基本类型(没有析构函数)释放内存时delete同delete[] (原则是与NEW NEW[]配对使用)
  4. 显示声明拷贝构造函数以实现深拷贝(否则自动生成浅拷贝版本),调用场景为:根据已有对象初始化新对象
  5. 显示声明赋值函数,若已实现深拷贝
  6. 重载二元操作符时,应使用友元函数(若使用成员函数实现则只需传递一个参数,另一个参数是自己)
    • 友元函数/类,是通往私有成员的后门。其设计宗旨是,一种外部函数/类也可以访问类的私有成员
    • 友元函数不属于类,因此实现时,不需要也不能加::
    • 友元函数不能使用this指针,因此使用时通常需要把类的对象作为参数传入
    • 友元函数的典型使用场景是:一个函数需要访问多个类
  7. 重载+返回的是临时对象,因此不能函数返回值类型不能是引用

C++拷贝构造&操作符重载的更多相关文章

  1. 拷贝构造和拷贝赋值、静态成员(static)、成员指针、操作符重载(day06)

    十七 拷贝构造和拷贝赋值 浅拷贝和深拷贝 )如果一个类中包含指针形式的成员变量,缺省的拷贝构造函数只是复制了指针变量的本身,而没有复制指针所指向的内容,这种拷贝方式称为浅拷贝. )浅拷贝将导致不同对象 ...

  2. C++中的赋值操作符重载和拷贝构造函数

    1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...

  3. C++ 进阶5 拷贝构造 深度复制 运算符重载

    C++ 进阶5 拷贝构造 深度复制 运算符重载 20131026 例子: 运行环境是G++ 编译, /* * main.cpp * *  Created on: 2013年10月26日 *      ...

  4. c++ 操作符重载和友元

    操作符重载(operator overloading)是C++中的一种多态,C++允许用户自定义函数名称相同但参数列表不同的函数,这被称为函数重载或函数多态.操作符重载函数的格式一般为: operat ...

  5. C++之旅:拷贝构造与友元

    拷贝构造与友元 拷贝构造是在构造一个对象的时候将已有对象的属性拷贝给新的对象:友元可以让一个类的所有属性(主要是private)对特定的类开放 拷贝构造 如果没有复写拷贝构造函数,系统会帮我们默认生成 ...

  6. [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符

    /* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...

  7. C++ 操作符重载 (operator)

    重载不能改变操作符的优先级 如果一个内建操作符是一元的,那么所有对它的重载仍是一元的.如果是二元的重载后也是二元的 下面看一个有代表性的例子:: 头文件Complex.h: #includeusing ...

  8. C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载

    1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...

  9. C++等号操作符重载

    在新学操作符重载时最令人头疼的可能就是一些堆溢出的问题了,不过呢,只要一步步的写好new 与 delete.绝对不会有类似的问题. 当时我们编译可以通过,但是运行会出错,因为对象s1与s2进行赋值时, ...

随机推荐

  1. iOS 8 之 新特性

    1. 沙盒间共享数据 2. Metal 3D绘图,据说10倍速,替代了OpenGL 3. AppStore 可视频预览

  2. 如何设置打开jsp页面速度加快?

    1.

  3. double减法不准确的那些事儿

    CREATE TABLE `helei` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `num1` double DEFAULT NULL ...

  4. Spinnerd的功能和用法

    此处的Spinner其实是一个列表选择框.不过Android的列表选择框并不是需要下拉列表的,而是相当于弹出一个菜单供用户选择. Spinner和Gallery都继承了AbsSpinner,AbsSp ...

  5. 如何在Visio 2007中画接口和实现类的关系图

    http://blog.sina.com.cn/s/blog_53fc9db50100as5o.html 在Visio图形元素上,点击右键,选择“形状显示选项”,将“实现链接”选中,这个时候,类图形元 ...

  6. C# 程序只能执行一次

    应用程序的主入口点. //每一个程序只能运行一个实例 bool isRun = false; System.Threading.Mutex m = new System.Threading.Mutex ...

  7. jQuery实践-别踩白块儿网页版

    ▓▓▓▓▓▓ 大致介绍 终于结束了考试,放假回家了.这次的别踩白块儿网页版要比之前做的 jQuery实践-网页版2048小游戏 要简单一点,基本的思路都差不多. 预览:别踩白块网页版 这篇博客并不是详 ...

  8. 黑客常用的windows注册表大全

    目录 使系统没有"运行"选项                        1让操作系统无"关闭系统" 选项                    2让操作系统 ...

  9. OGG学习笔记03-单向复制简单故障处理

    OGG学习笔记03-单向复制简单故障处理 环境:参考:OGG学习笔记02-单向复制配置实例 实验目的:了解OGG简单故障的基本处理思路. 1. 故障现象 故障现象:启动OGG源端的extract进程, ...

  10. Apple官方IOS开发入门教程[v0.2]

    今天,又跑去找IOS开发入门教程了,结果发现没什么好的PDF. 后来发现,原来苹果官方有开发入门教程,而且写的很好.所以整理出来了,给大家分享一下. 我就不在这里贴pdf的内容了,下面有苹果官方教程的 ...