通过c字符串对拷贝构造和赋值构造进行了解

简介: 通过c字符串对拷贝构造和赋值构造进行了解

通过cstring的处理进行熟悉知识点:

在进行赋值构造和复制构造时,主要涉及到对象的深拷贝和浅拷贝。

计算机默认是进行浅拷贝(有关构造函数中执行申请内存相关的变量,浅拷贝会拷贝地址而不是真正申请内存,会导致析构释放不匹配),涉及到相关的内存问题时,我们要注意自己对内存做处理,实现一些内存的申请和拷贝。

也可以使用delete关键字或者类的private特性禁用拷贝构造和赋值构造。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class MyString{
public:
  //构造函数 析构函数  拷贝构造函数  赋值构造函数
  MyString() { mystr = NULL; }
  ~MyString()
  {
    if(mystr != NULL)
    {
      free(mystr);
      mystr = NULL;
    }
  }
  //= NULL是没有参数和上面冲突了
  MyString(const char* cstr );
  MyString(const MyString &s);
  MyString &operator=( const MyString &str);
  void Print() 
  {
    printf("%s \n", mystr);
  }
private:
  char* mystr = NULL; //成员变量一定要注意初始化,在这里或者构造函数后面
};
MyString::MyString(const char* cstr)
{
  if(cstr == NULL)
  {
    mystr= NULL;
    // mystr = (char*)malloc(1);//申请内存过小,可能导致踩内存
    // mystr[0] = '\0';
    return ;
  }
  mystr = (char*)malloc((int)strlen(cstr)+1);
  memset(mystr, 0 , (int)strlen(cstr)+1);
  memcpy(mystr, cstr, (int)strlen(cstr)+1);
}
MyString::MyString(const MyString &s)
{
  if(this == &s)
  {
    return;
  }
  if(mystr != NULL)
  {
    free(mystr);
  }
  mystr = (char*)malloc((int)strlen(s.mystr)+1);
  memset(mystr, 0 , (int)strlen(s.mystr)+1);
  memcpy(mystr, s.mystr, (int)strlen(s.mystr)+1);
}
// CMyString & CMyString::operator = (const CMyString& cstr)
// {
//  //if(*this != cstr)
//  if(this == &cstr)
//  {
//    CMyString strtemp (cstr);
//    char * pTemp = temp.m_cstr; //这个应该是不合理的
//    strtemp.m_cstr = m_cstr;  //析构的时候会自动释放这个内存    
//    m_cstr = pTemp;    //替换了内存的指向
//  }
//  return *this;
// }
MyString & MyString::operator=( const MyString &str)
{
  if(this == &str)
  {
    return *this;
  }
  if(mystr != NULL)
  {
    free(mystr);
  }
  mystr = (char*)malloc((int)strlen(str.mystr)+1);
  memset(mystr, 0 , (int)strlen(str.mystr)+1);
  memcpy(mystr, str.mystr, (int)strlen(str.mystr)+1);
  return *this;
}
int main()
{
  MyString str("123");
  str.Print();
  MyString str1 = "1233";
  str1.Print();
//有问题的
  MyString str2(str1);
  str2.Print();
//有问题的  CMyString str3 = str;
  MyString str3 ;
  str3 = str;
  str3.Print();
  MyString str4;
  MyString str5;
  str4 = str5 = str2;
  str4.Print();
  str5.Print();
  return 0;
}
目录
相关文章
|
7月前
|
编译器 C++ 开发者
C++构造函数在数组中的使用
C++构造函数在数组中的使用
53 0
|
2月前
|
存储 C++ 容器
Map容器-构造和赋值讲解
Map容器-构造和赋值讲解
26 0
|
7月前
|
存储 安全 编译器
【C++11新特性】右值引用和移动语义(移动构造,移动赋值)
【C++11新特性】右值引用和移动语义(移动构造,移动赋值)
|
3月前
|
编译器 C++
【c++】构造函数赋值方式(初始化列表)
【c++】构造函数赋值方式(初始化列表)
|
3月前
|
安全 编译器 C语言
深入了解C++:形参、内联、重载、引用、const和指针、new和delete
深入了解C++:形参、内联、重载、引用、const和指针、new和delete
22 1
|
8月前
|
存储 编译器 C语言
【C++基础】类与对象(中):默认成员函数、构造函数、析构函数、拷贝构造、赋值重载函数……
【C++基础】类与对象(中):默认成员函数、构造函数、析构函数、拷贝构造、赋值重载函数……
66 0
|
10月前
|
C++
C++的引用 拷贝赋值和引用赋值
C++的引用 拷贝赋值和引用赋值
167 0
|
12月前
|
存储 编译器 C++
类的默认成员函数、赋值运算符重载(二)
如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
43 0
|
12月前
|
编译器 C++
类的默认成员函数、赋值运算符重载(一)
如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
70 0
【构造】构造一个字符串满足k个子序列问题总结
【构造】构造一个字符串满足k个子序列问题总结
【构造】构造一个字符串满足k个子序列问题总结