【Json11源码阅读】10 问题解答,Part_8

问题1

// This prevents Json(some_pointer) from accidentally producing a bool. Use  
// Json(bool(some_pointer)) if that behavior is desired.  
Json(void *) = delete;  

疑问

=delete的作用是什么?

解题思路

还是翻书,查找目录和c++11新特性目录,找到15.7.2 删除的拷贝控制和继承 P553。翻到这一页,书上又指明了,P450和P475已经出现过这部分内容。我们从P450看起。

解答

阻止拷贝

虽然大多数类应该定义拷贝构造函数和拷贝赋值运算符,但对某些类来说,这些操作没有合理的意义。在些情况下,定义类时必须采用某种机制阻止拷贝或赋值。

为了阻止拷贝,看起来可能应该不定义拷贝控制成员。但是,这种策略是无效的:如果我们的类未定义这些操作,编译器会为它生成合成的版本。

因此,在新标准中,我们通过=delete来解决这一问题。

通过将拷贝构造函数和拷贝赋值运算符定义为删除的函数来阻止拷贝。删除的函数是这样一种函数:我们虽然声明了它,但不能以任何方式使用它。

在函数参数列表后面加上=delete来指出我们希望将它定义为删除的函数

Json(void *) = delete;  

=delete告诉编译器,我们不希望定义这些成员。

不能把析构函数声明为删除的函数。如果析构函数被删除,就无法销毁此类型的对象了。因此,编译器将不允许定义该类型的变量或创建该类的临时对象

参考资料

《c++ Primer》P450


问题2

void dump(std::string &out) const;  
std::string dump() const {  
    std::string out;  
    dump(out);  
    return out;  
}  

疑问

这里对dump的结果提供了两种返回形式,可以在实际编程中借鉴。

std::string dump() const {}是内联的,在编译时展开

dump是使用频率很高的函数,使用两种形式返回结果对用户来说比较方便。

那么对比使用频率没那么高的函数,有没有必要定义两种形式返回结果呢?

我觉得是没有必要的。大家可以留言讨论


问题3

const char * in;  
std::string(in);  

疑问

不大记得了,string的其他构造?

解题思路

翻看以前的笔记

解答

初始化string对象的方式

string s1;  

string s2( s1 );  
string s2 = s1;  

string s3("value");  
string s3 = "value";  

string s4( n, 'c' )  

数组还可以用来初始化vector对象,只需要指明待拷贝区域的首尾元素地址就可以了

int arr[] = { 0, 1, 2, 3 };  
vector<int> ivec( begin(arr), end(arr) );  

建议:尽量使用vector和string,而非数组。数组和指针容易产生一些概念和理解上的错误

上面用数组来初始化vector的机制,有助于我们用vector来代替数组

那么,字符数组能否转换成string

允许使用以空字符结束的字符数组来初始化string对象或为string对象赋值

当然,如果需要也可以把string对象转换为指向字符的指针

const char *str = s.c_str();

参考资料

笔记


问题4

static inline std::vector<Json> parse_multi(  
    const std::string & in,  
    std::string & err,  
    JsonParse strategy = JsonParse::STANDARD) {  
    std::string::size_type parser_stop_pos;  
    return parse_multi(in, parser_stop_pos, err, strategy);  
}  

疑问

std::string::size_type parser_stop_pos;默认初始化得到的值是多少?

为什么使用std::string::size_type类型

解题思路

查看cppreference,没有得到解答

http://en.cppreference.com/w/cpp/string/basic_string

百度得到stackoverflow上的一个答案

http://stackoverflow.com/questions/1181079/stringsize-type-instead-of-int

解答

string::size_type是一个unsigned类型,parser_stop_pos默认初始化得到的值应当是0

至于为什么使用std::string::size_type类型,翻译stackoverflow上的一个答案如下:

shot和signed char都可以存放数字。但是当遇到一个超长的string时,他们的位数限制了他们所能表示的最大数字,以至于无法存放一个超长string的size。

但是string::size_type不同,无论string有多长,string::size_type都能存放其长度

举例说明为什么string::size_type是必要的:考虑一个64位的机器,int所占有的位数通常还是32bit,但是实际上你的内存所能存储的内容远远不止2的32次方bytes那么多。

所以如果使用int来表示string的长度,就没有办法创建一个长度大于2的31次方的string了。

但是string::size_type在64位的机器上是一个64bit的值,所以可以毫无问题的用来表示string的长度

参考资料


END


微信公众号:马志峰的编程笔记

记录一名普通程序员的成长之路

posted @ 2017-04-18 07:19  马志峰  阅读(383)  评论(0编辑  收藏  举报