- 如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字
- 指针的类型必须与其所指对象的类型一致,但允许令一个指向常量的指针指向一个非常量对象。
-
指针本身是一个常量并不意味着不能通过指针修改其所指对象的值,完全取决于所指对象的类型 //1 int errNumb = 0; int *const curErr = &errNumb; //这时执行*curErr = 0;是正确的。 //2 const double pi = 3.1415; //这是一个顶层const, const double *const pip = $pi; //这时执行*pip = 2.72;是错误的。靠右的是顶层,靠左的是底层,但是当赋值号右边时数字是,是顶层const
- 顶层const表示自己本身的类型, 底层const表示所指对象的类型。如果所指对象为“数”,则为顶层const
- 如果你认定变量是一个常量表达式,那就把它声明成constexpr类型
-
typedef char *pstring; const pstring cstr = 0; //const char* cstr = 0; const pstring *ps;
-
auto, decltype的使用:
-
使用decltype(ci) x = 0; 自动推导出ci的类型来给x命名;
-
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型,只是推导出表达式类型,而不是直接计算表达式的结果。
int i = 42, *p = &i, &r = i; //注:decltype((ariable))是引用,注意双括号。 decltype(r + 0) b; //b是表达式r + 0运算结果对应的类型, int decltype(*p) c; //错误,c是int& 类型, 必须初始化。
-
- getline(cin,line);//把换行符也读进来,但不写入line字符中,只是消除缓冲区中的“\n"。
- string中的size()函数返回类型,size_type
- int *ip[4]与int (*p)[4]的区别
- int *ip[4];数组长度为4,元素类型是整型指针
- int (*p)[4];p 是一个指针,指向长度为4的 数组,数组类型为int型。‘
- eg,int *(&array)[10] = ptrs; 首先array是一个引用,引用的对象是一个长度为10的数组,元素类型是整形指针。
- ++运算符高于*, *p++先移动再 *, *(解引用)低于点运算符。
- inline取决于编译器
- assert(expr)
- 形参与实参要用精准匹配。
- 指向函数的指针的使用:void ff(int *);调用方法:void (*pf3)(int *) = ff;类型和参数要匹配。
- 紧跟在参数列表后面的const表示this是一个指向常量的指针,像这样使用const的成员函数被称为常量成员函数。
std::string Sales_data::isbn(const Sales_data *const this){ reutrn this->isbn; }
因为this是指向常量的指针,所以常量成员函数不能改变调用他的对象的内容,但是除了mutable声明的变量之外。
-
Sales_data& sales_data::combine(const sales_data &rhs){ units_sold += rhs.units_sold; revenur += revenue; return *this; } total.combine(trains); //内置的运算符把它的左侧运算对象当成左值返回,因此为了与它保持一致,combine函数必须返回引用类型。
-
不能创建一个const的构造函数,因为只用构造函数完成初始化过程,对象才能真正取得其”常量“属性。
-
友元函数:可以访问一个类中的private数据成员,最好集中声明友元。友元声明对于用户来说,可以把别的类中的函数作为另一个类中的友元。
-
当带有参数的构造函数时,如果此时还需要不带参数的对象,一定要写出默认的构造函数。
-
void solve const(){ return *this; }//返回的是常量引用,不能改变该常量对象的值
-
类中成员初始化时,参数列表顺序与初始化顺序没有关系,与类中声明成员的顺序相同。
class X{ int i; int j; public: X(int val):j(val),i(j){}//错误,因为先初始化的是i };
-
assign的使用:将右边运算对象中所有元素拷贝到左边运算对象中。
-
/* emplace_front, emplace, emplace_back 直接隐式构造对象 */ c.emplace_back("987", 25, 15.99); //正确 c.push_back("987", 25, 15.99); //错误,需要显示生成对象,再放入c
-
获取容器的首尾元素值 ,
*c.begin(), c.front() //首 *(--c.end()), c.back()// 尾 //其中forward_list没有
-
如果容器是vector或string,且存储空间被重新分配,则指向容器的迭代器,指针和引用都会失效。[容器操作可能使迭代器失效]
-
const 变量必须初始化,但当是指针时,只需要指向一块内存即可。
-
const int i = 4; 因为4是常数,所以这里的const顶层,代表自己的类型。
-
allocator与new的区别,内存的分配与构造
-
alloc.destroy(p) //释放, alloc.deallocate(p,n);二者的区别
element first_free cap element---->first_free 时构造对象时自动分配的, first_free ---->cap 时construct自动分配的。
-
-
string s = "world"; //1 string t = s + "!"; //2 string h = "hi" + s; //3 /* 2和3调用的运算符重载时不一样的。 2是调用的s.operator+("!"); 3是调用的operator+("hi", s); 其中"hi"默认的类型时 const char* 类型 唯一的要求是至少有一个运算符对象是类类型,并且两个运算对象都能准确无语地转换为string */
- 动态数组不是数组类型。typedef int arrT[41]; //arrT是int[]。
- 析构函数体自身并不直接销毁对象,成员实在析构函数体之后隐含的析构阶段中被销毁的。二者不在一个阶段进行。
- c++中,当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定。为题:绑定的是哪个对象。
- 1)从派生类向基类的类型转换只对指针或引用有效。2)基类是无法转换为派生类的。
- 派生类的成员和友元只能访问派生类对象中的基类部分的受保护成员。
- 虚析构函数的使用:当删除一个指向派生类对象的基类指针时将产生未定义的行为。
- shared_ptr与make_shared配合使用。
- vector不支持push_front,但使用slist.insert(slist.begin(), "hello");将数据插入到第一个元素之前。
- 构造stack(push_back, pop_back, back),使用除array和forward_list之外的任何容器来构造
- 构造queue(back, push_back, front, push_front) 构造与list, deque上, 不能基于vector
- 构造priovity_queue(front, push_back, pop_back),构造与vector,deque, 不能时list
-
#include <numeric> int sum = accumulate(vec.cbegin(), vec.cend(), index); //index的类型决定了函数使用哪个加法运算符 equal(vec.cbegin(), vec.cend(), r.cbegin()); //判断两个迭代器是否相等,r的长度大于vec
-
插入迭代器:back_iterator