实现C++string的赋值函数

之前一直敲C语言,对C++有点疏忽了,前两天看到《剑指offer》一道关于这个问题解法的面试题,于是动手敲了一下,却发现自己给的解法只是初级解法。总结原因,还是自己没有充分利用C++的特性,只是站在C语言的角度在写C++程序。

首先,分析一下这个问题要求:

           1.实现对象赋值(深拷贝);

           2.传入对象应该是const的,防止对象的值被修改;

           3.应该有返回值,也就是说,要能作为左值;

           4.要有异常处理机制(这里使用if,没有使用try catch);

           5.还有最后一点,容易被忽略若开始时指针有指向,应该先释放这块空间,否则则会造成内存泄露,还有个细节就是,delete释放空间后,记得将指针的指向置为NULL(毕竟C++不好写,哈哈^-^);

           说到这里,我建议你可以试着实现一下以上的要求,可能你会和我一样,会给出课本上的那种所谓的“标准解法”,等你实现之后,你再看看我给出的参考《剑指offer》给出的“高级解法”,你可能会和我一样,感叹它的精妙。下面给出代码实现:

#include <iostream>
#include <new>
#include <cstring>
#include <cstdlib>
using namespace std;

class my_string
{
private:
    char *str_ptr;
public:
    my_string();
    my_string(char *str_ptr);
    my_string(const my_string &str);
    my_string &operator = (const my_string &str);
	void print();
	~my_string();
};
void my_string::print()
{
    cout << str_ptr << endl;
}
my_string::my_string(char *str_ptr)
{
    if (str_ptr == NULL) {
	    cerr << "argument is error" << endl;
	}
    this->str_ptr = new(nothrow)char[strlen(str_ptr) + 1];
	if (this->str_ptr == NULL) {
		cerr << "merrory is full" << endl;
		exit(1);
	}
	strcpy(this->str_ptr, str_ptr);
}
my_string::my_string(const my_string &str) 
{
    if (str.str_ptr) {
        this->str_ptr = new(nothrow)char[strlen(str.str_ptr) + 1];
	    if (this->str_ptr == NULL) {
	        cerr << "merrory is full" << endl;
            exit(1);
	    }
		
	    strcpy(this->str_ptr, str.str_ptr);
   }
}
my_string::~my_string()
{
    delete []str_ptr;
	this->str_ptr = NULL;
}
/******************************************************
 *********************高级解法*************************
 *****************************************************/
//使用临时变量的优势:
//1.将new的判错交给拷贝构造函数
//2.将this->str_ptr指向的原有单元的释放交给temp的析构函数
//3.从而简化了代码
my_string &my_string::operator = (const my_string &str)
{
    if (&str != this && str.str_ptr != NULL) {
	    my_string temp(str);
		char *temp_ptr = this->str_ptr;
		this->str_ptr  = temp.str_ptr;
		temp.str_ptr    = temp_ptr;
	}

	return *this;
}
my_string::my_string()
{
	str_ptr = NULL;
}
    
int main(int argc, char* argv[])
{
    char str[100] = {0};
	my_string *obj_ptr = NULL;	
	my_string obj1, obj2;

	cout << "Please input a string:" << endl;
    cin  >> str;
	obj_ptr = new(nothrow)my_string(str);
	
	if (obj_ptr == NULL) {
	    cerr << "memory is full" << endl;
	    exit(1);
	}

	obj1 = obj2 = *obj_ptr;
	obj1.print();
	obj2.print();
	obj_ptr->print();

	delete obj_ptr;
	obj_ptr = NULL;
}
注:赋值号重载的实现函数和《剑指offer》有些许细微差别,我觉得我这样写可能代码的健壮性更好一点。

C++中的字符串赋值函数、移动赋值函数和移动构造函数分别是: 1. 字符串赋值函数(Assignment Operator):在C++中,可以使用赋值操作符(=)来将一个字符串赋值给另一个字符串。例如: ```cpp std::string str1 = "Hello"; std::string str2; str2 = str1; // 使用赋值操作符将str1的值赋给str2 ``` 这里,使用赋值操作符将str1的值赋给str2。 2. 移动赋值函数(Move Assignment Operator):移动赋值函数用于在性能上优化对象的赋值过程,通过移动资源而不是进行深拷贝。它使用`&&`来接收右值引用参数。例如: ```cpp class MyString { public: // 移动赋值函数 MyString& operator=(MyString&& other) noexcept { if (this != &other) { // 释放当前对象的资源 delete[] m_data; // 移动other的资源到当前对象 m_data = other.m_data; m_size = other.m_size; // 清空other对象 other.m_data = nullptr; other.m_size = 0; } return *this; } private: char* m_data; size_t m_size; }; ``` 这里,移动赋值函数通过移动`other`对象的资源到当前对象,并清空`other`对象。 3. 移动构造函数(Move Constructor):移动构造函数用于在性能上优化对象的构造过程,通过移动资源而不是进行深拷贝。它使用`&&`来接收右值引用参数。例如: ```cpp class MyString { public: // 移动构造函数 MyString(MyString&& other) noexcept { m_data = other.m_data; m_size = other.m_size; other.m_data = nullptr; other.m_size = 0; } private: char* m_data; size_t m_size; }; ``` 这里,移动构造函数通过移动`other`对象的资源到当前对象,并清空`other`对象。 需要注意的是,移动赋值函数和移动构造函数一般需要保证不抛出异常,因此通常会使用`noexcept`关键字声明它们。另外,移动赋值函数和移动构造函数通常与移动语义相关的类一起使用,如智能指针、容器等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值