C++-创建安全的constchar*构造函数

C++ - creating safe const char* contructor

本文关键字:构造函数 constchar 创建 安全 C++-      更新时间:2023-10-16

我正在创建一个类,该类具有从const char*初始化的构造函数,该构造函数应该使用缓冲区中提供的数据安全地构造对象,该数据应该包含字符串。我担心的是,用户可能会将此构造函数与错误的数据一起使用,例如NULL指针或指向未分配内存的指针之类的数据。重点是,在这种情况下,我希望完成创建对象(它将处于未定义但正确的状态),而不会导致segfault,例如,如果用户向我发送了一个指向我不应该读取的数据的指针。我想把所有的输入验证发送到std::string构造函数,所以构造函数看起来像这样:

Foo(const char *s) : Foo(std::string(s)) {}

但我的老师称这是一个"错误的想法"。那么,处理这种情况的正确方法是什么呢?

还有一件事,在这种情况下,我不能使用例外(这是我课程中家庭作业的一部分,还没有教过)。

问题是有些东西你绝对无法检查。组中最大的是指向无效内存的指针。例如:

char* blarg = new char[50];
delete blarg;
Foo(blarg);

这是另一个关于你所问问题的对话。有一些好的答案,但它们基本上说的是一样的。在处理指针输入时,无法100%确定用户在传入指针之前没有对指针执行诸如调用delete之类的愚蠢操作。

我担心的是,用户可能会将此构造函数与错误的数据一起使用,例如NULL指针或指向未分配内存的指针之类的数据。重点是,在这种情况下,我想完成创建对象(它将处于未定义但正确的状态)

无法检测指针是否有效。调用方必须负责确保它指向已分配的内存。

但是,可以检测指针是否为空。您可以检查它,如果是,则在不取消引用指针的情况下设置对象的状态。

我想将所有输入验证发送到std::string构造函数

但我的老师称之为";错误的想法";。

你的老师是对的。这不会有帮助,因为std::string还要求并假设输入是有效的。使用无效指针构造它会导致未定义的行为。

那么,处理这种情况的正确方法是什么呢?

简单地要求调用方保证指针的有效性是正确的做法,也是你所能做的。如果你想检查null,请随时检查。

如果构造函数throw中有错误。这就是它的作用。对象不是构造的,并且客户端(传入错误指针的客户端)被正确地告知了这一点。

如果您想检查您的类是否只接受std::string作为参数和const char[],你可以写这样的东西:

class Foo {
public:
    template<typename U>
    Foo(U &&val, typename std::enable_if<std::is_same<typename std::remove_reference<U>::type, std::string>::value ||
        std::is_array<typename std::remove_reference<decltype(val)>::type>::value, void>::type* = nullptr): field_(val) {}
private:
    std::string field_;
};

然后:

Foo foo("aa");//accept
std::string str("bb");
Foo foo2(str);//accept
Foo fnull(NULL);//compile time error

当然,如果您只想将指针传递给char,则此解决方案不起作用。