繁体   English   中英

如何在构造函数的initializer-list中使用异常处理?

[英]How to use exception handling with initializer-list with constructor?

我曾经通过构造函数使用initialization list ,但一切进展顺利。 但是现在我需要在类中进行一些exception handling

所以这是一些示例代码:

1-无异常处理

class CVector{
    public:
        CVector(const int);
    protected:
        int* pInt;
        int size;
};

CVector::CVector(const int sz) :
    pInt{ new int[sz]}, size{ sz}{

}

上面的构造函数不会检查是否传递了无效的大小,或者new失败...

现在,我编辑了构造函数以处理异常:

2-带有异常处理:

CVector::CVector(const int sz){
    size = sz;
    if(size <=0 )
        throw; // some exception object

    pInt = new int[sz];
    if(nullptr == pInt)
        throw; // some memory exception
}
  • 现在的问题:它们是排他性的吗? -我的意思是如何通过构造函数将异常处理与初始化列表混合在一起?

乍看之下,不清楚您是否打算让CVector负责拥有整数的动态性。 你可能会的。

几乎可以肯定,您希望程序中的每个类最多管理一个动态资源(例如分配的内存)。 这是因为当资源不止一种时,工作变得很繁重。

在您的情况下,资源是int数组。 因此,让我们赋予CVector责任,并使用unique_ptr来管理该责任:

#include <memory>
#include <cstddef>
#include <algorithm>

struct CVector
{
    CVector(std::size_t initial_size)
    : data_ { std::make_unique<int[]>(initial_size) }
    , size_ { initial_size }
    {
    }

    // we will probably want the vector to be copyable
    CVector(CVector const& other)
    : data_ { std::make_unique<int[]>(other.size_) }
    , size_ { other.size_ }
    {
        auto first = other.data_.get();
        auto last = first + other.size_;
        std::copy(first, last, data_.get());
    }

    // move consruction is defaultable because it is enabled for
    // unique_ptr

    CVector(CVector&&) = default;

    // assignment

    CVector& operator=(CVector const& other)
    {
        auto temp = other;
        swap(temp);
        return *this;
    }

    CVector& operator=(CVector&& other) = default;

    // no need for a destructor. unique_ptr takes care of it

    void swap(CVector& other) noexcept
    {
        using std::swap;
        swap(data_, other.data_);
        swap(size_, other.size_);
    }

private:
    // defer memory ownership to a class built for the job.
    std::unique_ptr<int[]> data_;
    std::size_t size_;
};

1)将大小验证检查提取到一个单独的静态方法中(很可能无论如何都会重复使用); 2)不再需要检查new返回的值,如果失败,则应引发std::bad_alloc异常。 因此您的代码可以变成这样:

class CVector{
public:
    CVector(const int);
    static int Validate_Size(int const size);
protected:
    int * m_pInt;
    int m_size;
};

int CVector::Validate_Size(int const size)
{
   if(size <= 0)
   {
      throw std::invalid_argument{};
   }
   return(size);
}

CVector::CVector(const int size)
:  m_pInt{new int[Validate_Size(size)]}
,  m_size{size}
{}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM