检查指针args是否为空/应该在成员初始化列表中为原始指针初始化字段

我正在阅读有关实施“三五规则”的内容,并找到了有关cppreference的示例以及有关SO的规范答案我知道char*在现代C ++中使用没什么意义,但是重点是创建一些需要这三种方法的代码。

Cppreference开头类似:

class rule_of_three
{
    char* cstring; 
    rule_of_three(const char* s, std::size_t n) // n is passed from the public ctor
        : cstring(new char[n]) // allocate
    {
        std::memcpy(cstring, s, n); // populate
    }

public:
    rule_of_three(const char* s = "")
        : rule_of_three(s, std::strlen(s) + 1) 
    { }

...

但是,类不检查,如果snull的话-这不就是一个潜在的问题?

我试图这样写:

class rule_of_three
{
    char* cstring; 
    rule_of_three(const char* s, std::size_t n) 
    {
        if (!s) throw std::runtime_error("s cannot be null");

        cstring = new char[n]; // allocate
        std::memcpy(cstring, s, n); // populate
    }

但是现在海湾合作委员会抱怨说

rule_of_three::cstring 应该在成员初始化列表中初始化[-Weffc ++]

那么,这里正确的方法是什么?

埃雷里卡

但是该类根本不检查s是否为null —这不是潜在的问题吗?

仅当将null传递给构造函数时,这才是问题。否则不是。

第二个片段实际上具有null检查,这使我无法使用成员初始化列表。

空检查并不会阻止您使用成员初始化列表。这是一个例子:

static char*
init(const char* s, std::size_t n))
{
    if (s)
        return new char[n];
    else
        throw std::runtime_error("s cannot be null");
}

rule_of_three(const char* s, std::size_t n)
    : cstring(init(s, n))
{

那么,这里正确的方法是什么?

首先,忽略使用裸拥有指针的细节可能不是正确的方法:检查null和不检查null都是正确的方法。一个更安全,另一个更有效。您必须选择哪种对您的用例更重要。无论如何,建议初始化成员。


PS正如dratenik在评论中指出的那样,公共构造函数在委派给私有构造函数之前依赖于指针不为null,因此私有构造函数中的检查为时已晚。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章