35_运算符重载与智能指针

作业讲解

析构地址不同有多个的原因,一个delete调用会free空间,一个就是析构

运算符重载

    1. 只有类才有运算符重载
    2. 简化方法,如设置值可以直接使用等于号赋值
    3. 目标:代码简洁
    4. 功能:重载已有运算符赋予新的功能

语法

Class A

{

Public:

Void operator= (int n)

{

m_iX = n;

}

Private:

int m_iX;

};

全局函数重载运算符

    1. 需要使用friend联合使用

转换运算符

    1. 语法Operator TYPE
    2. 转换运算符重载,使用的时候需要重载
    3. 运算符重载优先级大于转换运算符

垃圾回收:自动delete,智能指针设计

    1. 使用一个类有这个类的数据成员,构造的时候保存这个类的地址,析构的时候释放这个类
    2. 重载指针可能出现的各种情况
    3. 避免=操作浅拷贝的时候重复释放还需要加上引用计数

注意

    1. 运算符重载不能破坏原有运算符的意义
    2. 运算符用法与原运算符一致
    3. 运算符重载支持函数重载
    4. 运算符重载的返回值还是当前类型,一般返回引用

作业

1.写一个hello类重载“()”使其像一个函数一样可以调用,并输出helloworld

 //Hello.h
#pragma once
#include 
using namespace std;

class CHello
{
public:
    CHello();
    ~CHello();
    void operator() ();
};
 //Hello.cpp
#include "Hello.h"

CHello::CHello()
{

}

CHello::~CHello()
{
}

void CHello::operator()()
{
    cout << "helloworld" << endl;
}

2.设计一个智能指针类,StuPtr里面含有一个Student类的指针,并重载->,在使用的时候和原指针一样而不用考虑内存释放这些麻烦的问题
即:
PerPtr per = new CPerson();
per->sayHello();
return 0;(CPerson中有sayHello方法)

 //Student.h
#pragma once
#include 

using namespace std;

class CStudent
{
public:
    CStudent();
    ~CStudent();
    void* operator new(size_t size);
    void sayHello();
};
 //Student.cpp
#include "Student.h"



CStudent::CStudent()
{
}


CStudent::~CStudent()
{
}

void* CStudent::operator new(size_t size)
{
    return malloc(sizeof(CStudent) * sizeof(char));
}

void CStudent::sayHello()
{
    cout << "Student sayHello" << endl;
}
 //StuPtr.h
#pragma once
#include "Student.h"

class CStuPtr
{
public:
    CStuPtr();
    ~CStuPtr();
    CStuPtr(CStudent* pObj);
    CStudent* operator-> ();
    CStuPtr& operator= (CStuPtr *pObj);
    CStuPtr& operator= (CStudent *pObj);
    void* operator new(size_t size);
private:
    CStudent *m_pStu;
};

 //StuPtr.cpp
#include "StuPtr.h"



CStuPtr::CStuPtr()
{
    m_pStu = (CStudent *)new CStudent;
}


CStuPtr::~CStuPtr()
{
    if (m_pStu != nullptr)
    {
        delete m_pStu;
        m_pStu = nullptr;
    }
}

CStuPtr::CStuPtr(CStudent * pObj)
{
    m_pStu = pObj;
}

CStudent* CStuPtr::operator-> ()
{
    return m_pStu;
}

CStuPtr& CStuPtr::operator=(CStuPtr *pObj)
{
    pObj->m_pStu = m_pStu;
    return *pObj;
}

CStuPtr& CStuPtr::operator=(CStudent *pObj)
{
    m_pStu = pObj;
    return *this;
}


void* CStuPtr::operator new(size_t size)
{
    return nullptr;
}

3.设计只有一个实例的类,不能使其实例化,
并且不能使其new和delete.

 //OnlyOne.h
#pragma once
class COnlyOne
{
private:
    COnlyOne();
    COnlyOne(COnlyOne& obj);
    void* operator new(size_t size);
    void* operator new[](size_t size);
    void operator delete(void* pointer);
    void operator delete[](void* pointer);
    ~COnlyOne();
    static COnlyOne m_only;
    int m_iX;
    int m_iY;
public:
    static COnlyOne* getInstance();
};
 //OnlyOne.cpp
#include "OnlyOne.h"



COnlyOne::COnlyOne()
{
    m_iX = 3;
    m_iY = 4;
}

COnlyOne::COnlyOne(COnlyOne & obj)
{
}

void * COnlyOne::operator new(size_t size)
{
    return nullptr;
}

void * COnlyOne::operator new[](size_t size)
{
    return nullptr;
}

void COnlyOne::operator delete(void * pointer)
{
}

void COnlyOne::operator delete[](void * pointer)
{
}


COnlyOne::~COnlyOne()
{
}

COnlyOne* COnlyOne::getInstance()
{
    return &m_only;
}

4.完善String类型增加以下运算符重载
operator=
operator+
operator[](int nIndex)
operator==
operator!=
operator>

5.写一个智能指针类,让string可以自动delete string对象

 //StrPtr.h
#pragma once
#include "MyString.h"

class CStrPtr
{
public:
    CStrPtr();
    CStrPtr(const char *str);
    CStrPtr(CStrPtr& obj);
    ~CStrPtr();
    CMyString* operator-> ();
    CMyString& operator* ();
private:
    CMyString* m_pStr;
};
 //StrPtr.cpp
#include "StrPtr.h"

CStrPtr::CStrPtr()
{
    m_pStr = new CMyString();
}

CStrPtr::CStrPtr(const char *str)
{
    m_pStr = new CMyString(str);
}

CStrPtr::CStrPtr(CStrPtr& obj)
{
    m_pStr = new CMyString(*obj);
}

CStrPtr::~CStrPtr()
{
    if (!m_pStr->IsEmpty())
    {
        delete m_pStr;
    }
}

CMyString* CStrPtr::operator->()
{
    return m_pStr;
}

CMyString& CStrPtr::operator* ()
{
    return *m_pStr;
}
 //MyString.h
#pragma once

class CMyString
{
public:
  CMyString();
  CMyString(const char* s);
  CMyString(CMyString& s);
  ~CMyString();
public:
  const char* GetBuff();
  int Length();
  bool IsEmpty();
  CMyString& Copy(const char* s);
  CMyString& Copy(CMyString& s);
  CMyString& Append(const char* s);
  CMyString& Append(char ch);
  CMyString& Append(int n);
  CMyString& Append(float f);
  CMyString& Append(double f);
  CMyString& Append(CMyString& s);
  CMyString& Append(bool b);
  CMyString& Append(long long n);
  CMyString& Format(const char* fmt, int count, ...);
  CMyString& Upper();
  CMyString& Lower();
  CMyString& operator= (CMyString& str);
  CMyString& operator+ (CMyString& str);
  char operator[] (int nIndex);
  bool operator== (CMyString& str);
  bool operator!= (CMyString& str);
  bool operator> (CMyString& str);
  static CMyString ValueOf(double d)
  {
    return CMyString().Format("%f", 1, d);
  }
private:
  void SetBuff(char *p);
  void SetLength(int len);
  void SetLimit(int limit);
  int GetLimit();
  void SetIsEmpty(bool IsEmpty);
  void AllocBuff(int len);
  void Init();
  void InitString(const char* s);
private:
  char* m_pBuff;
  int   m_Limit;
  int   m_Len;
  bool  m_IsEmpty;
};
 //MyString.cpp

#include "MyString.h"
#include 
#include 
#include 
#include 
CMyString::CMyString()
{
  Init();
}


CMyString::CMyString(const char* s)
{
  Init();
  InitString(s);
}

CMyString::CMyString(CMyString& s)
{
  Init();
  InitString(s.GetBuff());
}


CMyString::~CMyString()
{
  if (IsEmpty())
    return;

  if (GetBuff() != NULL)
  {
    delete[] GetBuff();
    SetBuff(NULL);
    SetIsEmpty(true);
  }
}

const char* CMyString::GetBuff()
{
  if (IsEmpty())
    return "NULL";

  return m_pBuff;
}

int CMyString::Length()
{
  return m_Len;
}

bool CMyString::IsEmpty()
{
  return m_IsEmpty;
}

CMyString& CMyString::Copy(const char* s)
{
  InitString(s);
  return *this;
}

CMyString& CMyString::Copy(CMyString& s)
{
  InitString(s.GetBuff());
  return *this;
}

void CMyString::SetBuff(char *p)
{
  m_pBuff = p;
}

void CMyString::SetLength(int len)
{
  m_Len = len;
}

void CMyString::SetLimit(int limit)
{
  m_Limit = limit;
}

int CMyString::GetLimit()
{
  return m_Limit;
}

void CMyString::SetIsEmpty(bool IsEmpty)
{
  m_IsEmpty = IsEmpty;
}

void CMyString::AllocBuff(int len)
{
  char *pBuff = new char[len];
  if (pBuff == NULL)
    return;

  SetBuff(pBuff);
  SetLimit(len);
}

void CMyString::Init()
{
  SetBuff(NULL);
  SetLimit(0);
  SetLength(0);
  SetIsEmpty(true);
}

void CMyString::InitString(const char* s)
{
  //1.是否为空
  if (IsEmpty())
  {
    int len = strlen(s) + 1;
    AllocBuff(len);
    SetLength(len - 1);
    strcpy_s(m_pBuff, GetLimit(), s);
    SetIsEmpty(false);
  }
  else
  {
    //不是空   
    int len = strlen(s) + 1;
    if (GetLimit() >= len) //空间够
    {
      SetLength(len - 1);
      strcpy_s(m_pBuff, GetLimit(), s);
    }
    else  //空间不够
    {
      int len = strlen(s) + 1;
      if (GetBuff() != NULL)
      {
        delete[] GetBuff();
        SetBuff(NULL);
      }

      AllocBuff(len);
      SetLength(len - 1);
      strcpy_s(m_pBuff, GetLimit(), s);
    }
  }
}

CMyString& CMyString::Append(const char* s)
{
  //1.是否为空
  if (IsEmpty())
  {
    Copy(s);
  }
  else
  {
    //不是空   
    int len = strlen(s) + 1 + Length();
    if (GetLimit() >= len) //空间够
    {
      SetLength(len - 1);
      strcat_s(m_pBuff, GetLimit(), s);
    }
    else  //空间不够
    {
      int len = strlen(s) + 1 + Length();

      char *pOldBuff = (char*)GetBuff();

      AllocBuff(len);
      SetLength(len - 1);
      strcpy_s((char*)GetBuff(), GetLimit(), pOldBuff);
      strcat_s((char*)GetBuff(), GetLimit(), s);

      if (pOldBuff != NULL)
      {
        delete[] pOldBuff;
      }
    }
  }

  return *this; 
}
CMyString& CMyString::Append(char ch)
{
  char s[2] = { ch,  0 };
  Append(s);
  return *this;
}

CMyString& CMyString::Append(int n)
{
  char s[20];
  sprintf_s(s, sizeof(s), "%d", n);
  Append(s);
  return *this;
}

CMyString& CMyString::Append(float f)
{
  char s[20];
  sprintf_s(s, sizeof(s), "%f", f);
  Append(s);
  return *this;
}

CMyString& CMyString::Append(double f)
{
  char s[20];
  sprintf_s(s, sizeof(s), "%f", f);
  Append(s);
  return *this;
}

CMyString& CMyString::Append(CMyString& s)
{
  Append(s.GetBuff());
  return *this;
}

CMyString& CMyString::Append(bool b)
{
  if (b)
    Append("true");
  else
    Append("false");

  return *this;
}

CMyString& CMyString::Append(long long n)
{
  char s[40];
  sprintf_s(s, sizeof(s), "%lld", n);
  Append(s);
  return *this;
}

CMyString& CMyString::Format(const char* fmt, int count, ...)
{
  char buffer[0x1000];
  va_list marker;
  va_start(marker, count);
  vsnprintf(buffer, sizeof(buffer),  fmt, marker);
  buffer[0x1000 - 1] = '\0';
  va_end(marker);

  Copy(buffer);

}

CMyString& CMyString::Upper()
{
  _strupr_s((char*)GetBuff(), GetLimit());
  return *this;
}

CMyString& CMyString::Lower()
{
  _strlwr_s((char*)GetBuff(), GetLimit());
  return *this;
}

CMyString& CMyString::operator=(CMyString& str)
{
    return Copy(str);
}

CMyString& CMyString::operator+(CMyString& str)
{
    CMyString *tmpStr = new CMyString();
    //1.当前字符串是否为空
    if (IsEmpty())
    {
        if (!str.IsEmpty())
        {
            tmpStr->Copy(str.GetBuff());
        }

        return *tmpStr;
    }
    else
    {
        //2.如果加法后面的为空字符串
        if (str.IsEmpty())
        {
            tmpStr->Copy(*this);
        }
        else
        {
            //获取两个字符串相加的结果
            int len = this->Length() + str.Length() + 1;
            char *pStr = new char[len];
            strcpy(pStr, this->GetBuff());
            strcat(pStr, str.GetBuff());
            tmpStr->InitString(pStr);
            delete[] pStr;
        }

        return *tmpStr;
    }
}

char CMyString::operator[](int nIndex)
{
    const char *pChar = nullptr;
    pChar = this->GetBuff();
    for (int i = 0; i < nIndex; i++)
    {
        pChar++;
    }

    return *pChar;
}

bool CMyString::operator==(CMyString& str)
{
    const char *pDest = nullptr;
    const char *pSoure = nullptr;
    bool isSame = true;

    pDest = this->GetBuff();
    pSoure = str.GetBuff();

    while ((*pDest!= '\0') || (*pSoure != '\0'))
    {
        if (*pDest != *pSoure)
        {
            isSame = false;
            break;
        }
        pDest++;
        pSoure++;
    }

    return isSame;
}

bool CMyString::operator!=(CMyString& str)
{
    if (*this == str)
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool CMyString::operator>(CMyString & str)
{
    bool isMoreThan = true;
    return isMoreThan;
}

 //string.cpp
#include 
using namespace std;
#include "MyString.h"
#include "StrPtr.h"

int main(int argc, char* argv[])
{
    /*
    CMyString str("34566");
    CMyString str2("345667");

    str2 + str;
    char a = str2[0];

    bool bIsSmall = str == str2;
    bool bIsNotSmall = str != str2;
    */

    {
        CStrPtr str2str2;
        CStrPtr str2("aaa");
        CStrPtr str3 = str2;
    }

	return 0;
}
0 条评论
发表一条评论