C ++ - 创建安全的const char * contructor

时间:2015-11-25 14:47:12

标签: c++ pointers constructor

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

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

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

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

4 个答案:

答案 0 :(得分:7)

问题是有一些你绝对无法检查的事情。该组中最大的一个是指向无效内存的指针。例如:

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

Here是关于你所问的问题的另一个对话。有一些好的答案,但他们基本上说同样的事情。处理指针输入时,无法100%确定用户没有做过愚蠢的事情,比如在传入之前调用指针上的删除。

答案 1 :(得分:2)

  

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

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

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

  

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

     

但我的老师称这是一个“错误的想法”。

你的老师是对的。这无济于事,因为std::string也需要并假设输入有效。使用无效指针构造它会导致未定义的行为。

  

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

简单地要求呼叫者保证指针的有效性是正确的 - 并且你能做到 - 。如果你想检查null,请随意这样做。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如果您想检查您的班级仅接受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的指针,这个解决方案就不起作用了。