随笔分类 -  C++ Primer学习笔记

摘要:C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系... 阅读全文
posted @ 2014-11-25 18:06 依然冷月 阅读(310) 评论(0) 推荐(0)
摘要:对于函数模板,编译器利用调用中的函数实参来确定其函数模板,从函数实参来确定模板实参的过程就被叫做是模板实参推导。比如: 1 #include 2 #include 3 using namespace std; 4 5 template 6 int compare(const T &v1, con... 阅读全文
posted @ 2014-10-21 17:54 依然冷月 阅读(413) 评论(0) 推荐(0)
摘要:在模板中,除了定义类型参数,我们还可以定义非类型参数。例如:temlateint foo(const char (&p1)[N], const char (&p2)[M]) { return strcmp(p1,p2);}但是需要注意的是:编译器会在一个字符串字面常量的末尾插入一个空字符作为终... 阅读全文
posted @ 2014-10-20 16:01 依然冷月 阅读(134) 评论(0) 推荐(0)
摘要:lambda表达式的捕获跟参数差不多,可以是值或者引用。1.值捕获 与传值参数类似,采用值捕获的前期是变量可以拷贝;与参数不通透的是:被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。void func(){ int v1 = 1; auto f = [v1] { ret... 阅读全文
posted @ 2014-10-16 16:36 依然冷月 阅读(2890) 评论(0) 推荐(0)
摘要:在一般的函数定义中,都是定义类似的函数。int foo(int v1, int v2);在调用foo函数的时候,将实参传进去就可以使用foo了。但是,我们也可以直接在函数定义的时候就给形参赋值。如:int foo(int v1 = 1, int v2 = 2);这样定义之后,可以这样使用:foo()... 阅读全文
posted @ 2014-05-29 16:49 依然冷月 阅读(132) 评论(0) 推荐(0)
摘要:Throw表达式和try块的定义如下:1. throw 表达式,错误检测部分使用这种表达式来说明遇到了不可处理的错误。可以说,throw 引发了异常条件。 2. try 块,错误处理部分使用它来处理异常。try 语句块以 try 关键字开始,并以一个或多个 catch 子句结束。在 try 块... 阅读全文
posted @ 2014-04-15 15:23 依然冷月 阅读(260) 评论(0) 推荐(0)
摘要:一、隐式转换规则:a.混合类型的表达式中,其操作数被转为相同的类型b.用作条件的表达式被转为bool类型c.用一表达式初始化某个变量,或将一表达式赋值给某个变量,则该表达式被转换为该变量的类型二、显示转换(强制类型转换)1.为什么要进行强制类型转换? a.需要覆盖通常的标准转换 b.可能存在多种转换,需要选择一种特定的转换方式2.转换形式: cast-name(expression); cast-name根据情况的不同,又分为static_cast、dynamic_cast、const_cast 和 reinterpret_cast。 ◆static_cast ・编译器隐式执行的任何类型... 阅读全文
posted @ 2014-04-01 15:00 依然冷月 阅读(175) 评论(0) 推荐(0)
摘要:1、new和delete都会用,这里只声明一点:C++ 没有明确定义如何释放指向不是用 new 分配的内存地址的指针。比如下面的代码: 1 #include 2 3 using namespace std; 4 5 int main() { 6 int i = 1; 7 int *p0 = &i; 8 int *p1 = new int(); 9 int *p2 = 0;10 11 delete p0; // Compile OK, Run Error12 delete p1; // Compile OK, Run OK13 ... 阅读全文
posted @ 2014-04-01 13:52 依然冷月 阅读(220) 评论(0) 推荐(0)
摘要:在C++ Primer中,有这样的一道习题:除了逻辑与和逻辑或外,C++ 没有明确定义二元操作符的求解次序,编译器可自由地提供最佳的实现方式。只能在“实现效率”和程序语言使用中“潜在的缺陷”之间寻求平衡。你认为这可以接受吗?说出你的理由。标准答案如下:可以接受,因为操作数的求解次序通常对结果没有什么影响。只有当二元操作符的两个操作数涉及同一对象,并改变该对象的值时,操作数的求解次序才会影响计算结果,后一种情况只会在部分(甚至是少数)程序中出现。在实际运用中,这种“潜在的缺陷”可以通过程序员的努力得到弥补,但“实现效率”的提高却能使所有使用该编译器的程序收益,因此利大于弊。个人理解:随着环境的不 阅读全文
posted @ 2014-04-01 11:02 依然冷月 阅读(421) 评论(0) 推荐(0)
摘要:先了解一下自增和自减的运算符:自增(++)和自减(--)操作符为对象提供加1或减1操作: int i = 0, j; j = ++i; // j = 1, i = 1: prefix yields incremented value j = i++; // j = 1, i = 2: postfix yields unincremented value因为前置操作返回加1后的值,所以返回对象本身,这是左值。而后置操作返回的则是右值。一个具体的例子来区分这个左值和右值: 1 #include 2 using namespace std; 3 4 void F(int a... 阅读全文
posted @ 2014-03-31 15:14 依然冷月 阅读(748) 评论(0) 推荐(0)
摘要:根据C++ Primer这本书上面的讲解,逗号表达式的定义如下:逗号表达式是一组由逗号分隔的表达式,这些表达式从左向右计算。逗号表达式的结果是其最右边表达式的值。如果最右边的操作数是左值,则逗号表达式的值也是左值。int main(){int x,y,z;x=y=1;z=x++,y++,++y;printf("%d,%d,%d\n",x,y,z);}上面的表达式中应该等价于这样的结合:(z=x++),y++,++y;如果这样写的话,则答案很清晰,为:2,3,1因为赋值运算符的优先级比逗号表达式的优先级要高一级,所以出现了上面的结果。--------------------- 阅读全文
posted @ 2014-03-31 14:16 依然冷月 阅读(563) 评论(0) 推荐(0)
摘要:因为多维数组就是数组的数组,因为我们可以这样来:int ia[3][4]; // array of size 3, each element is an array of ints of size 4 int (*ip)[4] = ia; // ip points to an array of 4 ints ip = &ia[2]; // ia[2] is an array of 4 ints 这样就OK了。*ip 是 int[4] 类型——即 ip 是一个指向含有 4 个元素的数组的指针。需要特别注意的是,加不加括号,是有很大区别的,比如:int *ip[4];... 阅读全文
posted @ 2014-03-27 16:51 依然冷月 阅读(201) 评论(0) 推荐(0)
摘要:例:编写程序读入一组 string 类型的数据,并将它们存储在vector 中。接着,把该 vector 对象复制给一个字符指 针数组。为 vector 中的每个元素创建一个新的字符数 组,并把该 vector 元素的数据复制到相应的字符数组 中,最后把指向该数组的指针插入字符指针数组。 1 #include 2 #include 3 #include 4 5 using namespace std; 6 7 int main() { 8 vector vect; 9 int vectCnt;10 11 cout > vectCnt) {13 vec... 阅读全文
posted @ 2014-03-26 17:31 依然冷月 阅读(302) 评论(0) 推荐(0)
摘要:1.动态数组的定义int* pInt = new int[10];此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指针 pInt;2.动态数组的初始化 上面的例子中,定义的数组是没有经过初始化的,其初始化的方式跟数组类似。 ①如果是类类型,那么不用显式的对它进行初始化,程序会默认调用类的构造函数为其进行初始化。string* pStr = new string[10]; ②如果是默认类型,则可以通过下面的方式进行初始化。int* pInt = new int[10](); ③const动态数组必须初始化。const int* 阅读全文
posted @ 2014-03-26 17:07 依然冷月 阅读(169) 评论(0) 推荐(0)
摘要:很经典的:const int* p;int* const p;前者表示指针指向的值是const,指向的值不可变,但是指针本身是可变的;后者表示改指针是const,指针不可变,但是指向的值是可变的。写个代码就是:const int* p = &a;*p = 123; // Errorp = &b; //OKint* const p = &a;*p = 123; // OKp = &b; // Error------------------------------... 阅读全文
posted @ 2014-03-24 15:04 依然冷月 阅读(146) 评论(0) 推荐(0)
摘要:数组很简单,但是还是有很多注意点。1.数组和容器(vector)的区别-两者都是基本的低级复合类型-只有在强调速度时才用数组和指针-数组长度是固定的,但是容器可以通过push_Back在其中自动添加元素2.数组定义和初始化-非const变量以及要到运行阶段才知道的const变量都不能用于定义数组的维数-在函数体外定义的内置数组,元素均被初始化为0-在函数体内定义的内置数组,元素无初始化-如果数组元素为类类型,则自动调用该类的默认构造函数进行初始化,如果没有默认的构造函数,则必须为该数组元素提供显式初始化-字符串字面值包含一个额外的空字符用于结束字符串,例:char ca[] = "C 阅读全文
posted @ 2014-03-16 00:01 依然冷月 阅读(148) 评论(0) 推荐(0)