Skip to content

Commit 7538c90

Browse files
committed
update many contents
1 parent 9cacd32 commit 7538c90

16 files changed

+272
-48
lines changed

C++/11_SmartPoint.md

+1
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ int main()
334334

335335
# 更多阅读
336336

337+
[Top 10 dumb mistakes to avoid with C++ 11 smart pointers](http://www.acodersjourney.com/2016/05/top-10-dumb-mistakes-avoid-c-11-smart-pointers/)
337338
[C++ 引用计数技术及智能指针的简单实现](http://www.cnblogs.com/QG-whz/p/4777312.html)
338339
[从auto_ptr说起](http://www.jellythink.com/archives/673)
339340
[到C++11中的智能指针](http://www.jellythink.com/archives/684)

C++/Basic.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void main( void )
6161
Test a(1); // 定义了一个对象
6262
a.fun(); // 调用对象的函数
6363
Test b(); // 声明了一个函数
64-
b.fun(); // Error!!!
64+
// b.fun(); // Error!!!
6565
}
6666
```
6767

C++/Class.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ const float A::e = 5;
238238

239239
## 成员函数
240240

241-
成员函数也可以被重载,只要满足重载的要求,即`同一个作用域内`的几个`函数名字相同``形参列表`不同,成员函数的 virtual 关键字可有可无。此外要注意**const函数与同名的非const函数是重载函数**;const对象只能调用const函数 ,但是非const对象可以调用const函数。
241+
成员函数也可以被重载,只要满足重载的要求,即`同一个作用域内`的几个`函数名字相同``形参列表`不同,成员函数的 virtual 关键字可有可无。
242242

243243
[const函数的操作](http://www.nowcoder.com/questionTerminal/09ec766d373a43769603963664e231e7)
244244

@@ -253,6 +253,22 @@ const float A::e = 5;
253253
* 隐藏:用什么就调用什么。
254254
* 覆盖:调用派生类。
255255

256+
**C++中成员函数能否同时用static和const进行修饰?**
257+
258+
不行!这是因为C++编译器在实现const的成员函数的时候为了确保该函数不能修改类的中参数的值,会在函数中添加一个隐式的参数`const this*`。但当一个成员为static的时候,该函数是没有this指针的,也就是说此时const的用法和static是冲突的。
259+
260+
更详细的解释如下:在定义一个类对象的时候,实际上只给该对象的非静态的数据成员分配内存空间(假设没有虚函数),而该类的静态成员数据以及该类的函数都在编译的时候分配到一个公共的空间里,所有,在定义一个对象并调用类对象的函数的时候,函数根本不知道到底是哪个对象调用了他,怎么解决这个问题呢?
261+
262+
C++利用传递this指针的方式来实现,调用一个类对象里的函数的时候,将把这个对象的指针传递给他,以便函数对该对象的数据进行操作,对于一个定义为const的函数,传递的是const的this指针,说明不能更改对象的属性,而对static成员的函数不传递this指针,所以不能用const来修饰static的成员函数了!
263+
264+
从对象模型上来说,类的非static成员函数在编译的时候都会扩展加上一个this参数,const的成员函数被要求不能修改this所指向的这个对象;而static函数编译的时候并不扩充加上this参数,自然无所谓const。
265+
266+
如果在编写const成员函数时,不慎**修改了数据成员,或调用了其他非const成员函数,编译器就会报错**。如果想在const函数中改变某个成员变量的值,那么可以将该变量声明为 mutable 类型。
267+
268+
此外,要注意**const函数与同名的非const函数是重载函数**,类的const对象只能调用const函数,非const对象可以调用const函数和非const成员函数。
269+
270+
具体的示例在 [C++_Class_Func.cpp](../Coding/C++_Class_Func.cpp)
271+
256272
# 继承
257273

258274
继承是类的重要特性。通过继承联系在一起的类构成一种层次关系,通常在层次关系的根部有一个基类,其他类则直接或者间接地从基类继承而来,这些继承得到的类称为派生类。基类负责定义在层次关系中所有类公同拥有的成员,而每个派生类定义各自特有的成员。
@@ -361,6 +377,7 @@ More Effective C++ 条款 27
361377
[深入理解C++的动态绑定和静态绑定](http://blog.csdn.net/chgaowei/article/details/6427731)
362378
[C++ 抽象类](http://www.cnblogs.com/balingybj/p/4771916.html)
363379
[关于C++中的虚拟继承的一些总结](http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/05/2537451.html)
380+
[类中的const成员](http://www.cnblogs.com/kaituorensheng/p/3244910.html)
364381
365382
366383
[1]: http://7xrlu9.com1.z0.glb.clouddn.com/C++_Class_1.png

C++/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ C++11修复大量缺陷和降低代码拖沓,比如lambda表达式的支持将
184184
《STL 源码剖析》
185185
《Effective C++》
186186
《More Effective C++》
187+
[C++ FAQ](https://isocpp.org/faq)
187188
[C++_More](More/C++_More.md)
188189
[C/C++内存管理详解](http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/)
189190
[那些不能遗忘的知识点回顾——C/C++系列](http://www.cnblogs.com/webary/p/4754522.html)

C++/Template.md

+75-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
使用模板的目的就是能够让`程序员编写与类型无关的代码`。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。
99

10-
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
10+
注意:**模板的声明或定义只能在全局,命名空间或类范围内进行。**即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
1111

1212
# 函数模板
1313

@@ -76,7 +76,7 @@ public:
7676

7777
## 成员函数
7878

79-
类模板的成员函数可以在类模板的定义中定义(这样就是 inline函数),也可以在类模板定义之外定义。要注意的是类模板成员函数本身也是一个模板,类模板被实例化时它并不自动被实例化,只有当它被调用或取地址,才被实例化。
79+
类模板的**成员函数可以在类模板的定义中定义(这样就是 inline函数),也可以在类模板定义之外定义**。要注意的是类模板成员函数本身也是一个模板,类模板被实例化时它并不自动被实例化,只有当它被调用或取地址,才被实例化。
8080

8181
在类模板外部定义成员函数的方法为:
8282

@@ -92,7 +92,76 @@ void A<T1,T2>::h(){
9292
}
9393
```
9494

95-
**当在类外面定义类的成员时template后面的模板形参应与要定义的类的模板形参一致**
95+
`当在类外面定义类的成员时template后面的模板形参应与要定义的类的模板形参一致`
96+
97+
# 模板编译
98+
99+
当编译器遇到一个模板定义时,并不生成代码。只有当我们实例化出模版的一个特定版本时,编译器才会生成代码。
100+
101+
**模板的声明和实现是否一定要在同一个头文件中?**
102+
103+
要知道,我们在调用一个函数时,编译器只需要掌握函数的声明。类似的,当**我们使用一个类类型的对象时,类定义必须是可用的,但成员函数的定义不必已经出现**。因此,可以将**类定义和成员函数声明**放在头文件(.h)中,而普通函数和类的成员函数的定义放在源文件中(.cpp)。
104+
105+
这样就可以把源文件编译成目标文件打包成库,然后把库和头文件给客户使用。对客户来说,可以使用相应的功能,但是看不到源文件。这样可以很好地保护商业利益,此外如果想要更改实现的话,可以重新编译自己的库,客户不需要为此更改代码。
106+
107+
但是在使用模板时,这种习惯性做法将变得不再有用。因为**为了生成一个实例化版本,编译器必须要掌握函数模板或类模板成员函数的定义**。因此,与非模版代码不同,模板的头文件通常既包括声明也包括定义。一般做法就是将模板的声明和定义都放置在同一个.h文件中,这就是为什么所有的STL头文件都包含模板定义。
108+
109+
详细来解释的话,主要从这[三个方面](https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl)来理解:
110+
111+
1. A template is not a class or a function. A template is a “pattern” that the compiler uses to generate a family of classes or functions.
112+
2. In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to “fill in” the template. For example, if you’re trying to use a Foo<int>, the compiler must see both the Foo template and the fact that you’re trying to make a specific Foo<int>.
113+
3. Your compiler probably doesn’t remember the details of one .cpp file while it is compiling another .cpp file. It could, but most do not and if you are reading this FAQ, it almost definitely does not. BTW this is called the “`separate compilation model`.”
114+
115+
下面看一个例子,假设一个模板类 Foo 的声明如下:
116+
117+
```c++
118+
template<typename T>
119+
class Foo {
120+
public:
121+
Foo();
122+
void someMethod(T x);
123+
private:
124+
T x;
125+
};
126+
```
127+
128+
成员函数的定义如下:
129+
130+
```c++
131+
template<typename T>
132+
Foo<T>::Foo()
133+
{
134+
// ...
135+
}
136+
template<typename T>
137+
void Foo<T>::someMethod(T x)
138+
{
139+
// ...
140+
}
141+
```
142+
143+
现在假设在 `Bar.cpp` 中使用 `Foo<int>`:
144+
145+
```c++
146+
// Bar.cpp
147+
void blah_blah_blah()
148+
{
149+
// ...
150+
Foo<int> f;
151+
f.someMethod(5);
152+
// ...
153+
}
154+
```
155+
156+
如果我们将Foo 的构造函数以及someMethod成员函数的定义放在Foo.cpp中,编译时会出现链接错误。这是因为编译器在编译 Foo.cpp 时知道了模版的定义代码,在编译 Bar.cpp 时候,知道了 Foo<int>的实例化,但是没法同时掌握模版定义和参数实例化,这样也就无法生成具体的类代码。
157+
158+
为了解决这个问题,通常我们会把模板的声明和定义放在一个头文件中(建议这样做),不过也可以分别放在头文件和源文件中,下面就是一个示例:
159+
160+
* [foo.h](../Coding/C++_Template_foo.h):函数模版声明,模版类的定义;
161+
* [foo.cpp](../Coding/C++_Template_foo.cpp):函数模版定义,模板成员函数的定义;
162+
* [main.cpp](../Coding/C++_Template_main.cpp):使用函数模版和模版类。
163+
164+
这里在模版类的实现文件中放置具体的`模版实例化`,就可以生成具体的实例化对象了。
96165

97166
# 隐式接口和编译期多态
98167

@@ -221,7 +290,10 @@ void f(){} // 注意:这里没有"模板实参"
221290
《Effective C++ 模板与泛型编程》
222291
《Effective C++ 条款 25》
223292
[Cpp Reference-Templates](http://en.cppreference.com/w/cpp/language/templates)
293+
[Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file)
294+
[Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file? ](https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl)
224295
[类模板定义及实例化](http://www.cnblogs.com/assemble8086/archive/2011/10/02/2198308.html)
225296
[C++ typename的起源与用法](http://feihu.me/blog/2014/the-origin-and-usage-of-typename/)
226297
[C++模板的偏特化与全特化](http://harttle.com/2015/10/03/cpp-template.html)
298+
[C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?](https://www.zhihu.com/question/20630104)
227299

Coding/C++_Class_Func.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* @Author: [email protected]
3+
* @Last Modified time: 2016-09-06 08:50:34
4+
*/
5+
6+
#include <iostream>
7+
using namespace std;
8+
9+
class A{
10+
public:
11+
A(int x): data(x){}
12+
void print_data() const{
13+
cout << "Data: " << data << endl;
14+
// set_data(1); Error
15+
// member function 'set_data' not viable: 'this' argument has type 'const A', but function is not marked const
16+
}
17+
void set_data(int x){
18+
data = x;
19+
print_data(); // no-const function call const function.
20+
}
21+
// Here we define a overload function.
22+
void set_data(int x) const{
23+
size = x; // mutable variable can be modified in const func.
24+
cout << "Size: " << size << endl;
25+
}
26+
27+
void update(int x){
28+
data = x;
29+
cout << "Data: " << data << endl;
30+
}
31+
32+
private:
33+
int data = 0;
34+
mutable int size = 0; // Can be modified in const function.
35+
36+
};
37+
38+
int main() {
39+
A a(2);
40+
a.set_data(10);
41+
a.print_data(); // No-const object call const function.
42+
const A b(-2);
43+
b.set_data(20); // Here const object call const function.
44+
// member function 'update' not viable: 'this' argument has type 'const A', but function is not marked const
45+
// b.update(10); Error.
46+
}
47+

Coding/C++_Template_foo.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* @Author: [email protected]
3+
* @Last Modified time: 2016-09-06 11:32:32
4+
*/
5+
6+
#include <iostream>
7+
#include "C++_Template_foo.h"
8+
template<typename T>
9+
void foo()
10+
{
11+
std::cout << "Here I am!\n";
12+
}
13+
14+
template<typename T>
15+
void Foo<T>::g()
16+
{
17+
std::cout << "Foo<T>::g()" << std::endl;
18+
}
19+
20+
// Important here, define the template function and class.
21+
template void foo<int>();
22+
template class Foo<int>;

Coding/C++_Template_foo.h

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <iostream>
2+
// Function template.
3+
template<typename T>
4+
void foo();
5+
6+
// Class template.
7+
template<typename T>
8+
class Foo {
9+
public:
10+
void f();
11+
void g();
12+
};
13+
template<typename T>
14+
inline
15+
void Foo<T>::f()
16+
{
17+
std::cout << "Inline function f()" << std::endl;
18+
}

Coding/C++_Template_main.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* @Author: [email protected]
3+
* @Last Modified time: 2016-09-06 11:32:51
4+
*/
5+
6+
#include "C++_Template_foo.h"
7+
int main()
8+
{
9+
foo<int>();
10+
11+
Foo<int> x;
12+
x.f();
13+
x.g();
14+
}

DataBase/Engine.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ MyISAM引擎使用B+Tree作为索引结构,**叶节点的data域存放的是
1212

1313
![][1]
1414

15-
这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址,这种索引方式叫做`非聚集索引`。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:
15+
这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址,这种索引方式叫做**非聚集索引**。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:
1616

1717
![][2]
1818

DataBase/SQL_More.md

+1-34
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,3 @@
1-
2-
3-
## 事务
4-
5-
事务是一组原子性的 SQL 查询,事务内的语句要么全部执行成功,要么全部执行失败。事务由 begin transaction 和 end transaction 之间执行的全体操作组成,这些步骤集合必须作为一个单一的、不可分割的单元出现。
6-
7-
事务具有一下特征(ACID):
8-
9-
* 原子性(Atomicity):事务中所有操作要么全部提交成功,要么全部失败回滚。对事务来说,不可能只执行其中的一部分。
10-
* 一致性(Consistency):数据库总是从一个一致的状态转换到另一个一致的状态。
11-
* 隔离性(Isolation):一个事务所做的修改在最终提交之前,对其它事务是不可见的。因此,每个事务都感觉不到系统中有其它事务在并发地执行。
12-
* 持久性(Durability):一旦事务提交,其所做的修改就会永久保存到数据库中。此时,即使系统崩溃,修改的数据也不会丢失。
13-
14-
SQL标准中定义了4种隔离级别,每一个级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高地并发,系统的开销也更低。
15-
16-
* READ UNCOMMITED(未提交读):事务中的修改,即使没有提交,对其它事务也都是可见的。可能发生`脏读`:即事务可以读取未提交的数据。(实际中很少使用)
17-
* READ COMMITTED(提交读):满足事务隔离性的简单定义:一个事务开始时,只能看见已经提交的事务所做的修改。这个级别有时候也叫做`不可重复读`,因为它不保证事务重新读的时候能读到相同的数据,因为在每次数据读完之后其他事务可以修改刚才读到的数据。考虑下面这种情况:A事务读取一个数据项var=1,然后B事务更新该数据var=2并提交,A事务接着又重新读了该数据,结果var=2,第二次读到的数据和第一次的不相同。大多数数据库系统的默认隔离级别是 READ COMMITTED(但是MySQL不是)。
18-
* REPEATABLE READ(可重复读):只允许读取已经提交的数据,而且`在一个事务两次读取一个数据项期间,其它事务不得更新该数据`。但该事务不要求和其它事务可串行化。可能存在`幻读`问题:当某个事物在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。可重复读是 MySQL 的默认事务隔离级别。
19-
* SERIALIZABLE(可串行化):最高的隔离级别,通过强制事务串行执行,避免前面的幻读问题。会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。
20-
21-
隔离级别与避免的问题如下表所示:
22-
23-
| 隔离级别 | 脏读可能性 | 不可重复读可能性 | 幻读可能性 |
24-
|---------|----------|---------------|-----------|
25-
|READ UNCOMMITED | ✔︎ | ✔︎ | ✔︎ |
26-
|READ COMMITTED || ✔︎ | ✔︎ |
27-
|REPEATABLE READ ||| ✔︎ |
28-
|SERIALIZABLE ||||
29-
30-
[允许不可重复读的隔离级别](http://www.nowcoder.com/questionTerminal/d843add07bfd480dbfe1c5401490a411)
31-
32-
参考
33-
[脏读、幻读和不可重复读 + 事务隔离级别](http://uule.iteye.com/blog/1109647)
34-
351
## 视图
362

373
让所有用户都看到整个逻辑模型是不合适的,此外有时候希望创建一个比逻辑模型更符合特定用户直觉的个人化的关系集合。因此,SQL 允许通过查询来定义`虚关系`,它在概念上包含查询的结果。虚关系并不预先计算并存储,而是在使用虚关系的时候才通过执行查询进行计算。任何像这种不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为`视图`(View)。
@@ -87,3 +53,4 @@ SQL 中用 create view 命令来定义视图,为了定义视图,必须给它
8753
《高性能Mysql》
8854
《数据库系统概念》
8955

56+

0 commit comments

Comments
 (0)