自定义字符串实现中c_str()函数中的constness问题

时间:2015-01-22 14:28:41

标签: c++

还是C ++的新手。我试图实现c_str()函数。我试过了:

class Str
{

public:
    typedef size_t size_type;
    typedef char* iterator;
    typedef const char* const_iterator;

const char* c_str() const {
    char* tmp = alloc.allocate(length + 1);
    alloc.construct(tmp + length + 1, '\0');
    for(size_type i = 0; i < length; ++i)
        tmp[i] = data[i];

    return tmp;
}

private:
    char* data;
    size_type length;

    std::allocator<char> alloc;
};

但我的编译器抱怨。看来,由于将函数定义为const,allocate()必须返回const指针(或者我得错了)。无论如何,这不起作用,我想知道是什么情况。

1)我知道我调用了allocate(),但我在新变量上调用它,而不是Str的成员。这就是我没有得到那个部分的原因 2)我知道&#34;返回数据&#34;但我想知道为什么这不会起作用。在C ++ 11中,c_str()和data()之间没有区别,但是我们仍然说:如果我总是这样做,我将如何区分这两者?&#34;返回数据;&#34;

2 个答案:

答案 0 :(得分:6)

c_str()的所有已知实现完成std::string的方式是为data中的一个附加字符保留空间并始终保持空终止,以便{{1只是c_str(),并且保证已经以空终止。

  

看来,由于将函数定义为const,allocate()必须返回const指针(或者我得错了)。

不,你肯定有问题。

代码中的问题是return data;在该成员函数中是const。您可以通过制作分配器的非常量副本来解决它:

alloc

这并不能使函数正确,因为每次调用它都会分配内存,因此调用者必须使用const char* c_str() const { std::allocator<char> alloc2(alloc); char* tmp = alloc2.allocate(length + 1); alloc2.construct(tmp + length + 1, '\0'); for(size_type i = 0; i < length; ++i) tmp[i] = data[i]; return tmp; } 释放它,即正确的接口std::allocator<char>

N.B。使用c_str()完全没有意义,你也可以std::allocator<char>::construct。即使使用tmp[length] = '\0'也毫无意义,您只需使用std::allocator<char>new即可。使用分配器的原因是允许用户使用备用分配器对其进行自定义,但如果您只是将其修复为仅使用delete[],则在使用分配器时没有真正的优势。所有,你只是让你的课程占用更多空间来存储毫无意义的std::allocator<char>成员。

此外,不应该是alloc

tmp + length

回复已修改的问题

  

1)我知道我调用了allocate(),但我在新变量上调用它,而不是Str的成员。这就是为什么我没有得到那个部分。

呃,不,你不是,你把它称为会员!

  

2)我知道&#34;返回数据&#34;但我想知道为什么这不会起作用。在C ++ 11中,c_str()和data()之间没有区别,但是我们仍然说:如果我总是这样做,我将如何区分这两者?&#34;返回数据;&#34;

为什么你想要在两者之间产生影响?

C ++ 03并不是说必须是两者之间的区别,它们是否相同,并且其中一个原因{{1} }和 alloc.construct(tmp + length + 1, '\0'); 在C ++ 11中是完全相同的,无论如何所有实现在C ++ 03中都是如此。它真的是唯一理智的方式。

让它们无缘无故只会使实现c_str()非常困难,因此这是一个非常愚蠢的设计选择。

答案 1 :(得分:0)

为什么不将数据作为const char *返回?没有人可以改变它,因为它是常量。

const char* c_str() const{
   return data;
}