cpp primer 第二章笔记
第二章主要讲的是基本类型,需要注意的有:
- 同一个表达式混用有符号和无符号数,会自动转换成无符号
- 字面值前缀指定字符编码,后缀指定变量大小或种类
字符串字面值不可修改(因为放在一个只读段中)
#include <iostream> int main(){ char *str="heheda!"; std::cout<<"before m: "<<str<<std::endl; str[3]='a'; std::cout<<"after m: "<<str<<std::endl; return 0; }$ ./cstr.out before m: heheda! [2] 37400 bus error ./cstr.outc++11提供了一种新的*列表初始化*,但是效率么。。。#include <iostream> #include <string> #include <vector> class tc{ public: tc(){std::cout<<"ct a class! "<<std::endl;} tc(const tc &t){std::cout<<"copy a class!"<<std::endl;} tc& operator=(tc &t){std::cout<<"= a class!"<<std::endl; return *this;} }; int main(){ tc t1; std::cout<<"==============="<<std::endl; tc t2(t1); std::cout<<"==============="<<std::endl; tc t3=t1; std::cout<<"==============="<<std::endl; tc t4{t1}; std::cout<<"==============="<<std::endl; tc t5={t1}; std::cout<<"==============="<<std::endl; std::vector<tc> tcv{t1,t2,t3}; return 0; }$ ./initlist.out ct a class! =============== copy a class! =============== copy a class! =============== copy a class! =============== copy a class! =============== copy a class! copy a class! copy a class! copy a class! copy a class! copy a class!所以在用容器时不要随便用初始化列表,详细见这里
const相关
- const变量只能初始化不能赋值(哈士奇都知道)
- 不加extern的const变量只能在本文件访问(所以说加了呢)
- const左值引用可以绑定:const变量,非const变量,常量(字面量,这也是std::string的设计,只能将字符串传给const std::string &,而不能传给std::string &),无论如何,常量左值引用意味着不能通过这个引用去修改变量
- 顶层const指指针本身的值是常量,底层const则是指针指向的值是常量,故而在函数传参或者复制指针时,顶层const忽略(反正就算你是常量我也只是复制你,后面无论怎么操作也不会修改你),底层const则不能忽略(因为有可能通过复制的指针修改数据)
constexpr常量表达式,由编译器帮忙检查;using的别名声明功能(类似typedef—)
单纯的auto的推断效果:忽略顶层const,然后把表达式的值算出来是啥类型auto就是啥类型。底层const保留。加const的auto推断出来才是顶层const的,auto &推断出来才是引用
decltype基本保留变量的所有属性,尤其是当变量为引用时推断出来的结果也是引用。当其表达式是解引用操作时,结果必为引用,而其跟双括号表达式(加了括号的变量),结果必为引用
注意类内初始值的初始化顺序:类内初始值-》构造函数初始化列表-》构造函数体
2016-07-21添加
我又回过头来看了一下,关于initializer_list,之前的示例代码中使用的是左值,所以拷贝了两次,但是当我给类添加移动构造函数并使用std::move将其转换为右值后:
std::cout<<"==============="<<std::endl;
std::vector<tc> tcv3{std::move(t1),std::move(t2),std::move(t3)};
===============
move a class!
move a class!
move a class!
copy a class!
copy a class!
copy a class!
出现了这种结果。 似乎不太对,按道理来说initializer_list的设计应该是为了方便用临时量来构造一个集合(按我自己的理解),既然是临时量标准库应该提供转移语义,现在看来并没有。其它的情况我找到了stackoverflow上的一个讨论,显然想要手动从里面转移出临时量也不可以,怪怪的感觉
