还是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;
答案 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;
}