通过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语言
通过指针引用字符串
通过指针引用字符串
93 1
|
5月前
|
Java
指针赋值的几种方法
指针赋值的几种方法
|
7月前
|
存储 C++ 容器
Map容器-构造和赋值讲解
Map容器-构造和赋值讲解
65 0
|
7月前
|
编译器 C++
【c++】构造函数赋值方式(初始化列表)
【c++】构造函数赋值方式(初始化列表)
|
7月前
|
存储 Java 索引
【Java数组】数组定义 | 初始化赋值 | 数组练习题
【Java数组】数组定义 | 初始化赋值 | 数组练习题
|
编译器 C++
36 C++ - 赋值(=)运算符重载
36 C++ - 赋值(=)运算符重载
33 0
|
人工智能 C语言 C++
指针引用字符串问题(详解)
通过指针引用字符串可以更加方便灵活的使用字符串。 字符串的引用方式有两种,下面简单介绍一下这两种方法。 1.用字符数组来存放一个字符串。 1.1 可以通过数组名和下标来引用字符串中的一个字符。 1.2 还可以通过数组名和格式声明符%s输出整个字符串。
150 1
|
API C++ Windows
c++中给LPCSTR赋值
c++中给LPCSTR赋值
|
存储 Unix PHP
变量的引用赋值与传值赋值
一、使用 memory_get_usage() 查看PHP内存使用量 1. 传值赋值
 变量的引用赋值与传值赋值