zoukankan      html  css  js  c++  java
  • 剑指offer-面试题1:赋值运算符函数

    题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数

     1 class CMyString
     2 {
     3 public:
     4     CMyString(char *pData=NULL);
     5     CMyString(const CMyString & str);
     6     ~CMyString(void);
     7 
     8 private:
     9     char * m_pData;
    10 };

    首先在解答这道题目之前,先要作一些说明:

    1.任何类都是默认的重载赋值操作符。

    2.类一旦被声明并且编译后就会为该类的实例分配内存。

    3.如果类的成员变量没有在堆(动态分配)中分配内存,那么无需重载赋值操作符也可。因为这样的赋值只

    是为每个成员变量赋值而已。

    比如:对象A有成员变量int a1

    1 A a;
    2 a.a1=1;
    3 A b;
    4 b.a1=2; 
    5 a=b;

    当执行到a=b;这一步的时候其实即使我们没有重载赋值操作符,也会调用类A的对象a的默认赋值函数

    1 void A::operate = (A b)
    2 { 
    3     this.a1=b.b1;
    6 }

    至此,对象a中的a1成功赋值为b1即2,没有问题的。

     

    接下来我们要考虑另外一种情况

    假如类A中有一个指针成员变量int *ptr;该ptr在构造函数中new了一块内存。

    那么我们重新考虑类A的两个对象a,b

    对象a,b分别有一个指针ptr,并且该指针在构造函数中分别new了一块内存我们分别以mema和memb表示。

    在a的ptr中new的内存mema中的值我们设为1,在b的ptr中new的内存memb中的值我们设为2.

    1 A a;/在构造函数new ptr(mema)
    3 A b;/在构造函数new ptr(memb)
    5 a=b;

    当我们执行到a=b这一步的时候,我们如果没有重载赋值操作符。那么

    1 void A::operate = (A b)
    2 {
    3      this.ptr=b.ptr;5 }

    乍看好像也没什么错,是的 this.ptr=b.ptr这句是将对象b.ptr的所指向的内推地址memb赋值给了a.ptr所

    指向的对象。好了问题来了,那么a.ptr所指向的那块内推是分配在堆中的也就所如果我们没有主动释放它

    是不会自动释放的。然而a.ptr已经指向了memb,这样很明显对象a出现了内存泄露。当然问题还不止于

    此,现在a.ptr和b.ptr都同时指向了memb.那么如果当对象a或者b结束后必然会释放掉memb,比如说a先结束

    释放memb,那么b.ptr是不是就成了野指针了呢,如果b先结束,那么a.ptr便成为了野指针,同时对象a还出现了内存泄露.

    那么你会问为什么之前直接赋值就可以而这里直接赋值就不行呢,这就涉及一个内存管理的问题,分配在堆的

    内存是需要我们用户自己释放的,而分配在栈的内存是由程序自己管理,程序结束后会自动释放。

     

    现在明白重载赋值操作符的场景了吧,

    那么还有几点需要说明:

    1.赋值操作符重载通常形参我们是引用,引用可以减少直接传值带来的构造开销.

    2.赋值操作符重载通常形参是常量,这是为了防止在赋值过程中操作符右值被修改。

    3.如果为了连续赋值应该把返回值类型声明为该类型的引用,否则函数的返回值为void,不能连续赋值。

    4.当然为我们还应该考虑传入的对象是否和被赋值对象是否相等。

     

    综合以上因素,这道题结果如下:

     1 CMyString& CMyString::operator = (const CMyString& str)
     2 {
     3     if(this==&str)
     4         return *this;
     5 
     6     delete []m_pData;
     7     m_pData=NULL;
     8 
     9     m_pData=new char[strlen(str.m_pData)+1];
    10 
    11     strcpy(m_pData,str.m_pData);
    12 
    13     return *this;
    14 }
  • 相关阅读:
    poj 3321 Apple Tree
    hdu 1520 Anniversary party
    Light OJ 1089 Points in Segments (II)
    Timus 1018 Binary Apple Tree
    zoj 3299 Fall the Brick
    HFUT 1287 法默尔的农场
    Codeforces 159C String Manipulation 1.0
    GraphQL + React Apollo + React Hook 大型项目实战(32 个视频)
    使用 TypeScript & mocha & chai 写测试代码实战(17 个视频)
    GraphQL + React Apollo + React Hook + Express + Mongodb 大型前后端分离项目实战之后端(19 个视频)
  • 原文地址:https://www.cnblogs.com/vpoet/p/4662589.html
Copyright © 2011-2022 走看看