题目一:赋值运算符函数

/////////////////////////////////////////////////////////////////////////////////////////////

// 3.题目一:赋值运算符函数

class CMyString

{

public:
     // 默认函数
     CMyString();
     CMyString(const CMyString&);
     CMyString& operator=(const CMyString&);
     ~CMyString();

void SetString(const char* pszStr)
     {
         // 释放旧数据
         Destroy();
         CopyData(pszStr);
     }

void Print()
     {
         if (m_pszData)
         {
             cout << m_pszData << endl;
         }
     }

void Destroy()
     {
         if (m_pszData)
         {
             delete [] m_pszData;
             m_pszData = NULL;
         }
     }

void CopyData(const char* pszStr)
     {
         if (pszStr)
         {
             int iLen = strlen(pszStr);
             m_pszData = new char[iLen + 1];
             strncpy(m_pszData, pszStr, iLen + 1);
             m_pszData[iLen] = ‘\0‘;
         }
     }

private:
     char* m_pszData;

};

// 默认构造函数

CMyString::CMyString()
     :m_pszData(NULL)

{

}

//拷贝构造函数

CMyString::CMyString(const CMyString& other)

{
     cout << "CMyString Copy Constructor!!!!" << endl;
     // 释放旧数据
     //Destroy();    // 这里不能释放,因为没有初始化

CopyData(other.m_pszData);

}

//赋值操作符

CMyString& CMyString::operator=(const CMyString& other)

{
     cout << "CMyString Assignment Operator!!!!" << endl;

#if 0   // 初级程序员!!!!
     if (this != &other)
     {
         Destroy();
         CopyData(other.m_pszData);
     }

#else
     //高级程序员 需要考虑异常 --> 内存不足,导致new char 抛出异常
     // 实现异常安全性:
     // 1.先new分配新内容在使用delete释放旧内容 --> 确保抛出异常时原来的数据不会被改变!!!
     // 2.先创建一个临时实例,再交换临时实例和原来的内容  --> 推荐这种方法!!!!
     if (this != &other)
     {
         // 调用拷贝构造函数创建临时实例
         CMyString strTmp(other);
         char * pTmp = strTmp.m_pszData;
         strTmp.m_pszData = m_pszData;   // strTmp调用析构函数时,会释放原来实例中的m_pszData!!!!
         m_pszData = pTmp;
     }

#endif
     return *this;

}

//析构函数

CMyString::~CMyString()

{
     Destroy();

}

void MyStringTestFunc()

{
     cout << "\n\n --------------- MyStringTestFunc Start -------------->" << endl;

CMyString str1;
     str1.SetString("Hello World!");
     str1.Print();

CMyString str2(str1);   // 调用拷贝构造函数
     str2.Print();

CMyString str3 = str1;  // 调用拷贝构造函数 等同于CMyString str3(str1)
     str3.Print();

CMyString str4;
     str4 = str1;            // 赋值操作符
     str4.Print();

cout << "\n\n --------------- MyStringTestFunc End -------------->" << endl;

}

原文地址:https://www.cnblogs.com/yzdai/p/11258583.html

时间: 2024-10-10 22:08:58

题目一:赋值运算符函数的相关文章

《剑指Offer》——试题1:赋值运算符函数

题目:如下类型为CMyString的声明,请为该类型添加赋值运算符函数. class CMyString { public: CMyString(char* pData = NULL); CMyString(const CMyString& str); ~CMyString(); private: char* m_pData; }; 关注点:      1.是否把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(即*this).只有返回一个引用,才可以允许连续赋值(str1=st

【剑指offer】赋值运算符函数

题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString { public: CMyString(char* pData = NULL); CMyString(const CMyString& str); ~CMyString(void); CMyString& operator = (const CMyString& str); private: char* m_pData; }; 解答: /*把参数申明为引用可以避免调用复制构造函

赋值运算符函数的返回值类型详解

在c++赋值运算符函数的学习中,对于返回值类型的问题,一直非常费解,今天彻底总结一些每种不同返回值类型的结果: 1.当返回值为空时: <span style="font-size:14px;">void hasptr::operator=(const hasptr& s)</span> 这个时候如果只有一个'='(a = b)运算那就没问题,但是如果存在'='(a = b = c)的链式操作时,编译器就会报错 我们看:a = b = c: 程序会先运行

剑指offer:赋值运算符函数

对于定义一个赋值运算符函数时,需要注意一下几点: (1)函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值 (2)传入的参数声明为常量引用,可以提高代码效率,同时赋值运算函数内不会改变传入的实例状态 (3)一定要记得释放实例自身已有的内存,否则程序容易出现内存泄露 (4)注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可. 代码未写

c++赋值运算符函数

请为该CMyString类型添加赋值运算符函数 浅拷贝: 其中深拷贝运行结果为: 浅拷贝运行结果为: 运行结果分析: 虽然两种都可以实现赋值运算符函数,但是第一种深拷贝,如果内存不足导致m_pData是一个空指针,在delete时将会导致程序崩溃,第二种便是一种高效且安全的方法. 总结:(1).在写程序时应注意new与delete.new[]与delete []搭配使用 (2).在返回时应引用返回,才可以连续赋值. (3).传入的参数写为常量引用,不仅可以提高效率,减少一次调用复制构造,并且在赋

请为CMyString类型编写构造函数、copy构造函数、析构函数和赋值运算符函数。

如下为类型CMyString的声明,请为该类型编写构造函数.copy构造函数.析构函数和赋值运算符函数. 1 class CMyString 2 { 3 public: 4 CMyString(const char* pData = nullptr); 5 CMyString(const CMyString& str); 6 ~CMyString(void); 7 8 CMyString& operator = (const CMyString& str); 9 10 void P

在赋值运算符函数中,类的实例能直接访问私有数据成员???

印象中,private的数据成员只能在类的成员函数中使用,无法通过类的对象直接访问!(错误理解) 正确的理解是:在类的成员函数中,可以直接访问私有成员.即只要在该类的成员函数中,无论是直接访问该类的私有数据成员,还是访问某个对象(必选是该类型)的私有数据成员,均是可以的!!! 借鉴网上(http://blog.csdn.net/iaccepted/article/details/34853937 )的说法就是: 实践证明,类(class)私有成员可以被类成员函数访问,不区分成员在哪个实例(ins

赋值运算符函数

class Solution { public: char *m_pData; Solution() { this->m_pData = NULL; } Solution(char *pData) { this->m_pData = pData; } // Implement an assignment operator Solution operator=(const Solution &object) { // write your code here if(this == &am

第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数

前言 如果你不想要编译器帮你自动生成的拷贝机制 (参考前文),那么你应当明确的拒绝. 如何拒绝?这便是本文要解决的主要问题. 问题描述 当你定义了一个类,而这个类中各对象之间也是封装的 - 禁止同类对象之间的相互赋值以及复制,那么你需要屏蔽掉编译器帮你生成的拷贝构造函数以及赋值运算符. 在许多代码中,会看到通过将拷贝构造函数和赋值运算符重载函数声明为私有且不予实现来实现这个功能.然而,这不是最科学的做法. 因为这没有做到真正的屏蔽:你在自己的成员函数中,或者友元函数中仍然可以调用这两个私有函数,