c++ - 如果不满足构造函数中的某些条件,是否可以导致新的 C++ 类实例失败?

标签 c++ class

据我了解,在C++中实例化一个新类时,返回一个指向新类的指针,如果内存不足,则返回NULL。我正在编写一个在构造函数中初始化链表的类。如果在初始化列表时出现错误,我希望类实例化器返回 NULL。

例如:

MyClass * pRags = new MyClass;

如果 MyClass 构造函数中的链表无法正确初始化,我希望 pRags 等于 NULL。我知道我可以使用标志和额外的检查来做到这一点,但我想尽可能避免这种情况。
有谁知道这样做的方法吗?

最佳答案

这里常用的方法是抛出一个异常(并在更高的地方处理它)。

异常机制的好处之一是它允许您从类构造函数中抛出异常。在那种情况下,您永远不会遇到指针返回无效的情况。您将在相应的 catch block 中“获得控制权”。如果指针仅在 try block 内声明(或在 try block 调用的其他一些方法中),它将超出您在该 catch block 中的范围。

这不是 hack - 它是非常合法且常见的编程技术。 例如,如果您的类构造函数动态分配内存(例如,用于内部缓冲区)并且此分配失败,您可能希望抛出异常,因为在构造函数主体的末尾您将没有有效的对象。

这是一个例子(过去 10 年我一直在做 Java,所以我下面的 C++ 代码很可能在这里搞砸了,也许有人可以为我编辑它)

// Begin C++ code written by a Java programmer... :)
class Myclass
{
   public:
      Myclass(int length)
      {
          if(length<=0) throw BadBufferSizeException("Bla bla bla");         
          this->buffer = (char*)malloc(length*sizeof(char)); // don't remember the new syntax
      }

      void doSomething()
      {
          // Code for placing stuff in the buffer
      }
    private:
      char* buffer;
};


int main()
{
   try
   { 
     int len;
     len = getLengthFromUser();
     MyClass* pMyClass = new MyClass(len);
     myClass->doSomething();
    } catch(const Exception & e)
    {
       // Whatever... Note how pMyClass is not even accessible here
    }
}

请注意,如果您在 try block 之外将 pMyclass 定义为 null,然后仅在创建类时在 try block 内重新分配它,在失败的情况下您可能仍然是 null,但您永远不会执行做一点事()。如果您担心初始化,您也可以将 doSomething() 调用移到 try-catch block 之外,但您需要确保您的指针不为空。

另请注意,与其他语言相比,C++ 在抛出东西时为您提供了更多(太多?)自由。我通常喜欢拥有异常类的层次结构或使用具有这种层次结构的现有库。

关于c++ - 如果不满足构造函数中的某些条件,是否可以导致新的 C++ 类实例失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2724579/

相关文章:

C++ 嵌套类错误 "cannot convert ... in assignment"

javascript - 在 typescript 中扩展方法

c++ - CUDA - 源文件上的 __device__ 方法

c++ - 如何确定 unicode 字符的字体和布局信息?

使用正向和反向迭代器的 C++ 映射删除

python-2.7 - 尝试调用 def 时,我得到 : parameter 'self' unfilled

swift - 如何在 swift 中声明一个 'protected' 变量

c++ - 如何返回/复制 unique_ptr<unsigned char[]> 的值?

android - JNI 检测到应用程序错误 : can't call void android. graphics.Canvas.drawBitmap

c++类模板特化,无需重新实现一切