C++学习之路 day4

Day4知识点:

myString类对象自我实现以及部分实验源代码:

//myString.h
#ifndef MYSTRING_H
#define MYSTRING_H
#include <stdio.h>


class myString
{
public:
    myString(const char *p =NULL);
    myString(const myString& another);
    myString& operator=(const myString& another);   //运算符重载
    myString operator+(const myString& another);
    bool operator>(const myString& another);
    bool operator<(const myString& another);
    bool operator==(const myString& another);
    char& operator[](int idx);
    char at(int idx);
    char* str();
private:
    char* _str;
};


#endif // MYSTRING_H
//myString.cpp
#include "mystring.h"
#include <string.h>




myString::myString(const char* p)
{
    if(p == NULL)
    {
        _str =new char[1];
        *_str = '\0';
    }
    else
    {    _str = new char[strlen(p)+1];
        strcpy(_str,p);
    }
}


myString::myString(const myString& another)
{
      _str = new char[strlen(another._str)+1];
      strcpy(_str,another._str);
}


myString& myString::operator=(const myString& another)
{
    if(this == &another)
    return *this;
    delete []_str;
    _str = new char[strlen(another._str)+1];
    strcpy(_str,another._str);
    return *this;
}


myString myString::operator+(const myString& another)
{
    myString tmp;
    delete []tmp._str;


    int len = strlen(this->_str);
    len +=strlen(another._str);


    tmp._str = new char[len+1];
    memset(tmp._str,0,len+1);


    strcat(tmp._str,this->_str);
    strcat(tmp._str,another._str);
    return tmp;


}


bool myString::operator>(const myString& another)
{
    if(strcmp(this->_str,another._str)>0)
        return true;
    else
        return false;
}


bool myString::operator<(const myString& another)
{
    if(strcmp(this->_str,another._str)<0)
        return true;
    else
        return false;
}


bool myString::operator==(const myString& another)
{
    if(strcmp(this->_str,another._str)==0)
        return true;
    else
        return false;
}


char& myString::operator[](int idx)
{
    return this->_str[idx];
}


char myString::at(int idx)
{
    return this->_str[idx];
}


char* myString::str()
{
    return _str;
}
//main函数
#include <iostream>
#include "mystring.h"
using namespace std;


#if 0
int main()
{
//   string a("***************");
//   string b;
//   string c("china");
//   cout<<a<<endl;
//   cout<<b;
//   cout<<c<<endl;
    myString a("***************");
    myString b;
    myString c("china");
    cout<<a.str()<<endl;
    cout<<b.str();
    cout<<c.str()<<endl;
    myString s("aa");
    myString s3(s);
    myString s4;
    s4 = s;
    myString s5("bb");
    s5 = s5;
    cout<<s.str()<<endl;
    cout<<s3.str()<<endl;
    cout<<s4.str()<<endl;
    cout<<s5.str()<<endl;


    return 0;
}
#endif


#if 0
int main()
{
    myString s1("abc");
    myString s2("def");
    myString s3 = s1 + s2;
    cout<<s3.str()<<endl;
}
#endif


int main()
{
    myString s1("bbc");
    myString s2("aef");
    if(s1>s2)
        cout<<"s1 > s2"<<endl;
    else if(s1 ==s2)
        cout<<"s1 == s2"<<endl;
        else
        cout<<"s1 < s2"<<endl;
    return 0;


}




1.  拷贝构造器,格式:A(const A & another) ;若不提供,系统会自动提供默认的。

myString::mystring(const myString& another)
{
    _str = another._str; //此处_str为myString类的私有成员,在同类之间是没有隐私的
}

2.如2中的浅拷贝myString s(s3);(在类中开辟空间的情况下)若不作处理或用系统提供的默认构造函数,会导致内存的重析构 double free,原因(s和s3的_str指向相同的内存空间,在析构时会析构两次)。应该如此修改




myString::myString(const myString& another)
{
      _str = new char[strlen(another._str)+1];
      strcpy(_str,another._str);
}

3.拷贝构造

1)  格式 类名(const 类名 &another),依附于原有对象创建新对象;

A a;
A b(a);
A c = b;


2)若不提供,系统会提供默认,一旦自定义,系统不再提供默认;

3)系统提供的默认,是一种等位拷贝。也就是浅拷贝;

4)浅拷贝,在某些情况下,会导致内存重析构(如2所示,含有堆空间的情况下),即double free(有些系统编译时提示错误,有些系统编译通过).要自己实现拷贝构造。

4.赋值重载

1)格式 类名 operator=(const myString& another);两个对象都已经创建好之后的赋值行为。

A c;
A a;
c = a;


2)编译器提供默认,一旦自定义,系统不再提供默认;

3)默认赋值运算符也是一种等位赋值,浅赋值;

4)浅赋值,可能会导致:a)自身发生内存泄漏;b)内存发生重析构;c)自赋值。应该如此修改


myString& myString::operator=(const myString& another)
{
    if(this == &another)
    return *this;
    delete []_str;
    _str = new char[strlen(another._str)+1];
    strcpy(_str,another._str);
    return *this;
}


5.建立类时的必要构造函数

Class A
{
pubilc:
    A();    //一般情况下要标配,即无参的情况包含默认数据,如A(int i = 0):a(i){}
    ~A();
    A(const A& another);
    A& operator=(const A& another);
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值