头文件 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. Python3基础 global关键字 使函数的局部变量升格为全局变量

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  2. JavaScript 开发工具webstrom使用指南

    本文给大家推荐了一款非常热门的javascript开发工具webstrom,着重介绍了webstrom的特色功能.设置技巧.使用心得以及快捷键汇总,非常的全面. 看到网上一篇介绍webstrom的文章 ...

  3. Angular - - $rootScope.Scope

    这里讲的是一些scope的操作,如创建/注销/各种监听及scope间的通信等等. $rootScope.Scope 可以使用$injector通过$rootScope关键字检索的一个根作用域. 可以通 ...

  4. Selenium2(java)selenium常用API 四

    WebElement相关方法 1.点击操作 WebElement button = driver.findElement(By.id("login")); button.click ...

  5. delphi edit编辑框使用

    Delphi编辑框Edit的用法 http://wenku.baidu.com/link?url=oKKm0VFBXexqiWt9ZNB8WxFGzwjJqRBM3ohrAy6GSMmOmwIzSWP ...

  6. FMS中的onStatus

    在FlashCom中的Camera, Microphone, LocalConnection, NetConnection,NetStream和 SharedObject对象都提供了事件响应,onst ...

  7. Spring生命周期各种接口使用

    1,BeanPostProcessor接口:不能在POJO上面使用,需要单独找一个类进行使用:如果在POJO上面实现了此接口,在实现了其他*Aware接口之后,这个接口方法将不会被调用:2, POJO ...

  8. Unity 容器教程

    文章摘自: http://www.cnblogs.com/qqlin/archive/2012/10/18/2720830.html

  9. B+树的插入、删除(附源代码)

    B+ Tree Index B+树的插入 B+树的删除 完整测试代码 Basic B+树和B树类似(有关B树:http://www.cnblogs.com/YuNanlong/p/6354029.ht ...

  10. DB2_自动生成值

    生成数字序列的两种方法 在 DB2 中可以用两种方法自动生成一个数字序列: 定义带有 IDENTITY 属性的列. 创建 SEQUENCE 对象. IDENTITY 列 当用 IDENTITY 属性定 ...