赋值运算符重载:错误处理方案

时间:2015-09-23 08:35:16

标签: c++ string

在回答问题之前,请参考以下程序。在评论中解释了代码。

所以我的问题是在赋值运算符重载如何处理new()无法分配内存的情况。

例如Obj1持有字符串"GeeksQuiz"。将Obj2分配给Obj1。在分配(在赋值运算符重载函数中)时,首先我们释放Obj1,然后使用Obj1值重新创建Obj2。那么在new无法分配内存如何保留旧的Obj1值的情况下呢?因为我们在函数启动时释放了Obj1个值。

我想要的只是在分配操作失败时使用Obj1的旧值。

请帮帮我。我想要完美的代码,没有任何内存泄漏,涵盖所有场景。在此先感谢

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

class String
{
private:
    char *string_data;
    int size;
public:
    String(const char *str = NULL); // constructor
    ~String() { delete [] string_data;  }// destructor
    void print() { cout << string_data << endl; } // Function to print string
    String& operator = (const String &); // assignment operator overload
};

String::String(const char *str)  // Constructor
{
    size = strlen(str);
    string_data = new char[size+1];
    if (string_data != NULL)
        strcpy(string_data, str);
    else
        cout<<"compiler failed to allocate new memory";
}

String& String::operator = (const String &str) // assignment operator overload
{
    if(this != &str) 
    {
        delete [] string_data; // Deleting old data and assigning new data below
        size = str.size;
        string_data = new char[size+1];
        if(string_data != NULL) // This condition is for cheking new memory is success 
            strcpy(string_data, str.string_data);
        else
            cout<<"compiler failed to allocate new memory"; // My quetsion comes in this scenario...
    }
    return *this;
}

int main()
{
    String Obj1("GeeksQuiz");
    String Obj2("stackoverflow");

    Obj1.print(); // Printing Before assigment
    Obj2.print();

    Obj1 = Obj2;  // Assignment is done. 

    Obj1.print(); // Printing After assigment
    Obj2.print();
    return 0;
}

3 个答案:

答案 0 :(得分:2)

临时或虚拟变量。

分配新内存,指定临时变量的指针。如果成功释放旧内存并重新分配该指针变量。

伪代码:

char *temp = new char[new_size];
std::copy(new_data, new_data + new_size, temp);
delete [] old_data;
old_data = temp;
old_size = new_size;

答案 1 :(得分:2)

首先,实现一个健壮的字符串很困难,除非你想为了学习目的而这样做,总是使用std::string

然后考虑operator new总是返回非空指针(除非您还实现了非标准的自定义new运算符),否则如果失败则抛出std::bad_alloc异常分配数据。如果要处理分配失败案例,则需要添加try-catch块

char *data = NULL;
try {
  data = new char[str.size + 1];
} catch (std::bad_alloc &e) {
  std::cout << "Allocation failed: " << e.what() << std::endl;
  throw; // <- You probably want to rethrow the exception.
}
strcpy(data, str.string_data);
delete [] string_data;
string_data = data;
size = str.size;

重要的部分是在抛出异常时让您的类处于一致状态,这就是您必须先分配新数据然后如果成功的原因,请删除旧数据。但是,bad_alloc异常很少在类级别处理,通常你会抛出异常(这就是我重新抛出代码示例的原因)并让客户端代码处理它。

如果你真的希望你的代码是异常证明,我会建议使用智能指针,如前所述,在这种情况下使用std::string

答案 2 :(得分:0)

第一个在临时变量中分配内存,如果它成功则只删除旧值。