C++实验一:移动语义

代码仅供参考
基本功能已实现,代码可自由复制、修改、转载。

课程名称: 面向对象技术(C++)
实验项目: 移动语义
实验仪器: 计算机

实验目的

1. 验证左值与右值的区别;验证右值引用的使用;

2. 设计并验证移动构造函数和移动复制函数的定义与使用,及其带来的效率提升;

实验内容 

1. 参考std::string,设计并实现MyString类。

基本功能要求:

1)四种构造函数、析构函数;

2)重载赋值操作符=,使其正确完成String类型的赋值操作

3)重载必要的操作符实现形如 String a = Hello ; a += World!;的功能。

4)重载必要的操作符实现形如 String a, b, c;  c = a + b; 的操作过程。

5)重载必要的操作符当完成 

    String a(Hello );

    a << world;

   的操作过程后,a所代表的字符串为Hello world

6)重载必要的操作符当完成

   String a(test);

   std::cout << a; 的操作过程后在屏幕上输入 test

7)重载必要的操作符当完成

   String a(test);

   a[2] = S; ,a所代表的字符串为teSt

设计及性能要求:

尽可能的高效实现上述MyString类。要给出关于设计思想的描述或是对设计过程做出必要说明和解释。

(一)函数

#include <iostream>
#include<string.h>
#include <chrono>
using namespace std;
class MyString{
public:
    char *_str{nullptr};
    int _length=0;
    public:
        int getl(){
            return _length;
        }
    MyString()=default;
    ~MyString(){//析构函数

        delete[] _str;

    };
   MyString(const char* str){
       if(str==nullptr)
       return;
       _length=strlen(str);
       _str=new char[_length+1];
       strcpy(_str,str);
   }
   //拷贝构造函数
   MyString(const MyString& other):_length{other._length}{
       if(other._str==nullptr)return;

       _str=new char[_length+1];
       strcpy(_str,other._str);
}
    //移动构造
    MyString(MyString &&other):_length{other._length},_str{other._str}{
    other._length=0;
    other._str=nullptr;
    }

    MyString operator+(const MyString &str){
        MyString result;
        result._length=_length+str._length;
        result._str=new char[result._length+1];
        strcpy(result._str,_str);
        strcat(result._str,str._str);
        return result;
    }
   MyString operator +=(char * str){
       _length=strlen(str)+_length;
       char *t=_str;

       _str=new char[_length+1];
       strcpy(_str,t);
       strcat(_str,str);
        delete []t;
        return *this;

   }

    MyString& operator=(const MyString &str){
        delete []_str;
        _length=str._length;
        _str=new char[_length+1];
        strcpy(_str,str._str);
        return *this;
}
    MyString &operator=(char *str){
        _length=strlen(str);
        delete [] _str;
        _str=new char[_length+1];
        strcpy(_str,str);
        return *this;
    }


 friend std::ostream&  operator<<(std::ostream& os, const MyString& str) {
        os << str._str;
        return os;
    }
     char& operator[] (int index) {
        if (index < 0 || index >= _length) {
            cout << "索引越界\n";
            exit(1);
        }
        return _str[index];
    }
};


int main()
{
    MyString s1;
    s1=("哥们名叫丁真!");
    cout<<s1<<endl;
    MyString s2="Smoke cigarettes by rules,";
    cout<<s2<<endl;
    s2+="我的小马名字叫珍珠。";
    cout<<s2<<endl;
    MyString a,b,c;
    b="假烟发现就跑路\n";
    c="Baby I ain't smoking by your rules";
    a=b+c;
    cout<<a<<endl;
    MyString s3("臭要饭的别挡我财路\n");
    s3<<"Why you always so poor";
    cout<<s3<<endl;
    MyString end("zood");
    cout<<end<<endl;
    end[0]='Z';
    cout <<end;



    return 0;
}

2.编写相应的测试用例,验证上述功能(包括内存使用的正确性)。

 

3.编写相应的测试用例,验证移动语义带来的效率提升,并给出分析与解释。

  • 实验过程

1)构造函数:接受一个 char* 类型的字符串作为参数,创建一个 MyString 类型的对象。

MyString(const char* str){

       if(str==nullptr)

       return;

       _length=strlen(str);

       _str=new char[_length+1];

       strcpy(_str,str);

   }

2)拷贝构造函数:接受一个 MyString 类型的对象作为参数,创建一个新的 MyString 类型的对象,它的值与参数对象相同。

   //拷贝构造函数

   MyString(const MyString& other):_length{other._length}{

       if(other._str==nullptr)return;

       _str=new char[_length+1];

       strcpy(_str,other._str);

}

  1. 移动构造函数:接受一个右值引用的 MyString 类型对象作为参数,创建一个新的 MyString 类型的对象,它的值与参数对象相同,并将参数对象的指针置为 null。

 //移动构造

    MyString(MyString &&other):_length{other._length},_str{other._str}{

    other._length=0;

    other._str=nullptr;

    }

  1. 拷贝赋值运算符:接受一个 MyString或char* 类型的对象作为参数,将当前对象的值设置为参数对象的值。

MyString operator +=(char * str){

       _length=strlen(str)+_length;

       char *t=_str;

       _str=new char[_length+1];

       strcpy(_str,t);

       strcat(_str,str);

        delete []t;

        return *this;

   }

    MyString& operator=(const MyString &str){

        delete []_str;

        _length=str._length;

        _str=new char[_length+1];

        strcpy(_str,str._str);

        return *this;

}

    MyString &operator=(char *str){

        _length=strlen(str);

        delete [] _str;

        _str=new char[_length+1];

        strcpy(_str,str);

        return *this;

    }

5)连接赋值运算符:接受一个 char* 类型的字符串作为参数,将其拼接到当前对象的末尾,并返回当前对象的引用。 

 MyString operator +=(char * str){

       _length=strlen(str)+_length;

       char *t=_str;

       _str=new char[_length+1];

       strcpy(_str,t);

       strcat(_str,str);

        delete []t;

        return *this;

   }    }

  1. 输出运算符:重载 << 运算符,用于将 MyString 类型的对象输出到标准输出流。MyString operator<< (char *str){

         _length=strlen(str)+_length;

       char *t=_str;

       _str=new char[_length+1];

       strcpy(_str,t);

       strcat(_str,str);

        delete []t;

        return *this;

索引运算符:重载 [] 运算符,接受一个整数类型的索引作为参数,返回当前对象中对应位置的字符。

public:friend std::ostream&  operator<<(std::ostream& os, const MyString& str) {

        os << str._str;

        return os;

    }

  

  • 功能验证

int main()

{

    MyString s1;

    s1=("哥们名叫丁真!");

    cout<<s1<<endl;

    MyString s2="Smoke cigarettes by rules,";

    cout<<s2<<endl;

    s2+="我的小马名字叫珍珠。";

    cout<<s2<<endl;

    MyString a,b,c;

    b="假烟发现就跑路\n";

    c="Baby I ain't smoking by your rules";

    a=b+c;

    cout<<a<<endl;

    MyString s3("臭要饭的别挡我财路\n");

    s3<<"Why you always so poor";

    cout<<s3<<endl;

    MyString end("zood");

    cout<<end<<endl;

    end[0]='Z';

    cout <<end;

    return 0;

}   

性能测试

MyString s1("Hello");

    int n_iterations = 10000000;

    {

        auto start = std::chrono::high_resolution_clock::now();

        for (int i = 0; i < n_iterations; ++i) {

            MyString s2(s1);    //调用拷贝构造函数

        }

        auto end = std::chrono::high_resolution_clock::now();

        std::chrono::duration<double> elapsed_seconds = end - start;

        std::cout << "Time taken by " << n_iterations << " copy constructor calls: "

                  << 1000.0 * elapsed_seconds.count() << "ms\n";

    }

    {

        auto start = std::chrono::high_resolution_clock::now();

        for (int i = 0; i < n_iterations; ++i) {

            MyString s3(std::move(s1));    //调用移动构造函数

        }

        auto end = std::chrono::high_resolution_clock::now();

        std::chrono::duration<double> elapsed_seconds = end - start;

        std::cout << "Time taken by " << n_iterations << " move constructor calls: "

                  << 1000.0 * elapsed_seconds.count() << "ms\n";

    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值