Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何处理C++;?_C++_C++11_Exception Handling_New Operator_Assignment Operator - Fatal编程技术网

C++ 如何处理C++;?

C++ 如何处理C++;?,c++,c++11,exception-handling,new-operator,assignment-operator,C++,C++11,Exception Handling,New Operator,Assignment Operator,我有一个带有赋值运算符的类,如下所示 char *buff; myString& operator= ( const myString& other ) { cout << " myString::operator=\n"; if( this != &other ){ cout<<"my string ="<<endl; delete [] buff; lengt

我有一个带有赋值运算符的类,如下所示

char *buff;
myString& operator= ( const myString& other )
{
  cout << "  myString::operator=\n";
  if( this != &other ){      
    cout<<"my string ="<<endl;
    delete [] buff;              
    length = other.length;      
    buff = new char[length];
    my_strncpy( buff, other.buff, length );
  }
  return *this;   
}       
char*buff;
myString和operator=(const myString和other)
{

cout处理内存不足的情况很困难,因为通常没有简单的故障路径可供使用

在您的情况下,您可以在删除旧缓冲区之前尝试创建新缓冲区,但这可能会增加内存不足(OOM)的可能性

理想情况下,如果旧缓冲区足够大,您可能应该使用它,如果旧缓冲区太小,则只创建新缓冲区。在这种情况下,在OOM事件中使用旧缓冲区可能是不明智的,因为它太小,无法存储字符串

如何使用
new
处理分配内存期间发生的任何异常

应该使用
try{}catch(){}
来捕获分配和对象创建期间抛出的异常

在异常情况下,如何将
buff
的值恢复为旧值

这里的关键不是在抛出异常时恢复旧值,而是首先分配和复制内容,交换指针等,然后删除旧对象和内存。这样,如果抛出异常,当前内容保持不变

首先将内存分配给一个临时指针,复制所需的数据,然后将新指针替换为旧指针并删除旧数据;类似于.GotW(#59)也有一篇关于这方面的好文章

一般来说,内存不足的情况非常严重,因此仅捕获异常可能并不总是理想的-它需要由整个应用程序来处理,甚至可能由整个系统的用户来处理。要问自己的一个问题是:您将如何处理异常,如何从中恢复


一个更通用的解决方案(我假设您确实专注于以当前形式实现
操作符=
)是使用完整的拷贝交换实现

class myString {
  char* buff;
  std::size_t length;
  // ...
};

myString::myString(myString const& src) :
buff(src.length ? new char[src.length] : nullptr),
length(src.length)
{
  if (length)
    std::copy(src.buff, src.buff + length, buff);
}

myString::~myString()
{
  delete [] buff;
  length = 0;
}

void myString::swap(myString& rhs)
{
  std::swap(rhs.buff, this->buff);
  std::swap(rhs.length, this->length);
}

myString& myString::operator=(myString const& rhs)
{
  if (this != &rhs) {
    myString temp(rhs);
    swap(temp);
  }
  return *this;
}

// the rest of the class implementation

//... non-member swap for addition utility
inline void swap(myString& lhs, myString& rhs)
{
  lhs.swap(rhs);
}

有两种解决方案。第一种(最好)是使用复制和交换:

myString& operator= ( myString other ) {
    swap (*this, other);
    return *this;
}
如果复制构造函数中的分配失败,我们将永远无法进行交换,因此不必担心覆盖当前状态。有关更多信息,请参阅

另一种方法是确保只有在安全的情况下才
删除
。也就是说,在
新建
之后执行:

tmp_buff = new char[other.length];
// either that threw, or we're safe to proceed
length = other.length;
my_strncpy(tmp_buff, other.buff, length);
delete [] buff;              
buff = tmp_buff;

这似乎是一个很容易回答的问题,但它真的是您想要的吗?您可以在删除缓冲区之前将该值存储在某个globale temp变量中。您可能会收到此代码的
bad_alloc
异常,并且可以使用try-catch块处理该异常。首先,您需要确定这是否是一个合理的ac过程当内存不足时,会出现异常。在赋值后,对象会无声地保留其旧值,这听起来很不确定。更简单的解决方案是使用
std::vector
进行内存分配。您所说的代码std::swap(temp_buff,buff);delete[]是什么意思temp_buff;@sasikala.
std::swap
将交换指针的值(而不是指向的值),因此旧指针现在取代了新指针和新指针。
delete[]
然后删除旧数据。请参阅我的注释myString&operator=(const myString&other){if(this!=&other){try{delete[]buff;length=other.length;//删除buff的内存后,我在为buff重新分配内存时遇到异常,请重试{buff=new char[other.length];//如果我在此处遇到异常,将不会执行超出此点的语句。//在这种情况下,如何将旧值获取到buff中。}catch(std::bad_-alloc&e){//处理bad_-alloc…}catch(std::exception&e){//处理异常}}@sasikala。分配缓冲区时会出现什么异常?我们可以说bad_-alloc-exception。无论何时,我们都不能在buff=new char[other.length]之后执行语句.我说的对吗?那么有没有办法恢复这些值。
tmp_buff = new char[other.length];
// either that threw, or we're safe to proceed
length = other.length;
my_strncpy(tmp_buff, other.buff, length);
delete [] buff;              
buff = tmp_buff;