【问题标题】:c_str implemenation for String classString 类的 c_str 实现
【发布时间】:2016-01-15 22:36:39
【问题描述】:

我正在阅读 Accelerated C++ 书中关于实现 string 类的第 12 章。

有一个章末问题来实现c_str() 函数。我正在寻找一些想法。

这是我目前所拥有的:

我的第一次尝试是堆分配char * 并返回它。但这会导致内存泄漏:

cost char * c_star() const {
   //cannot get reference to result later
   //causes memory leaks

   char* result = new char[data.size() + 1];
   std::copy(data.begin(), data.end(), result);
   result[data.size()] = '\0';
   return result;
}

这是另一个尝试:

const char* c_str() const {
    //obviously incorrect implementation as it is not NUL('\0') terminated.
    return &data[0];
}

我不能push_back '\0' 到数据,因为它不应该改变数据。

这里是spec

返回一个指向数组的指针,该数组包含以空字符结尾的字符序列(即 C 字符串),表示字符串对象的当前值。

这是本书的实现:(重命名为Str)。在内部,字符存储在矢量实现 (Vec) 中。

class Str {
    public:
       .
       .
       .

    private:
        Vec<char> data;
};

【问题讨论】:

  • return &amp;data[0]; 如果您始终为'\0' 留出足够的空间(并且始终将其放在那里,或者确保在必要时添加它),那么return &amp;data[0]; 将起作用。请记住,对于 C++11,它必须是 O(1) 操作,所以您几乎必须这样做。你不能分配+复制,因为那至少是O(n)
  • @nos 在这种情况下你不能标记c_str() const,因为它会改变数据成员。
  • @Revolver_Ocelot:查看 C++ mutable 关键字。惊喜! :-)
  • @Revolver_Ocelot 没有什么能阻止实现更改底层数组中的元素,即使 c_str() 被标记为 const。 (你甚至不需要可变的 keyworkd 来做到这一点)。
  • @Revolver_Ocelot ideone.com/ufvuwW ,这甚至不是警告。对于 std::string 的 c_str() 它也不会破坏任何语义,您没有任何业务可以访问 str.data() + str.length(),因此,如果 const 方法更改了您无法观察到的内容,则没有害处 有几个问题说明了原因这很好,参见例如stackoverflow.com/questions/293857/…

标签: c++ string accelerated-c++


【解决方案1】:

基于 cmets,我实现了 Str 类以确保每个字符串的末尾都有一个 NUL('\0')。我将数据存储在字符数组中,而不是向量:

class Str {
    public:
        typedef char* iterator;
        typedef const char* const_iterator;
        .
        .
        .
        //c_str return a NUL terminated char array
        const char* c_str() const { return str_beg; };
        //c_str and data are same as implementation make sure there is NUL
        //at the end
        const char* data() const { return str_beg; };
        .
        .
        .

    private:
        iterator str_beg;
        .
        .
        .
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2023-01-11
    • 2011-10-27
    • 1970-01-01
    • 2012-04-17
    • 2021-07-27
    相关资源
    最近更新 更多