《thinking in c++》Volume 1知识点总结(一)
2015-06-29 14:40
323 查看
Chapter3: The C in C++
1、利用vector模拟二维数组:
vector<vector<double>> v(m,vector<double>(n)) 是模拟一个含m个数组类型元素的数组,其中每个元素都是一个拥有n个double元素的数组
2、C++中可以随时定义变量;但C中应该在域内最开始定义
3、C++中常量定义:const int x=10,变量在定义时必须被初始化,编译阶段有type checking;C中常量定义:#define PI 31.4,编译阶段没有type checking,只是单纯的替换
4、assert(__condition__) 是一个宏,而不是函数
5、C++中的explicit cast:
static_cast<Typename T> (运用情况:castless conversion,narrowing conversion,conversion from void*)
const_cast<Typename T> (运用情况:conversion from const or volatile)
reinterpret_cast<Typename T> (运用情况:cast to a completely different meaning——most dangerous)
dynamic_cast<Typename T> (运用情况:for type-safe downcasting)
Chapter4: Data Abstraction
1、C与C++中类或结构体的区别:
C结构体:只是将数据成员分装在一起,对外部是完全可见的;用户必须自己定义初始化和清除函数;相关函数必须把要访问的结构体的指针传给函数;易造成结构体之间函数名冲突
C++类:将数据成员与成员函数封装在一起,对外部是部分可见的;通过构造函数和析构函数完成类的构建与清除;成员函数(非static)中有隐含的this指针,可直接访问数据成员,无需显式传递类对象指针;类之间函数名不会发生冲突
2、类对象的size不能为0:
class B{
void f(){ }
};
...
int main(){
B b;
double d; //&b and &d would be the same if the size of B is zero
}
3、C++头文件中structure,class重复声明是不被允许的 (使用preprocessor来解决这一问题)
#ifndef SIMPLE_H
#define SIMPLE_H
struct simple{
...
};
#endif
4、内嵌类或结构体:将相关元素封装在一起
class Stack{
struct Link{
...
}*head;
...
};
5、Global scope resolution:在成员函数中引用一个全局变量
int a;
void f(){ }
struct B{
int a;
void f(){
::f();
::a++;
a--;
}
};
Chapter5: Hiding the Implementation
1、Access control:C++通过public、private、protected等关键字实现类中数据成员对于外部的部分可见
public: 任何函数都可以访问
private: 只可以被成员函数访问
protected: 只可以被派生类和成员函数访问
2、friend关键字:friend函数可以访问类的全体数据成员
class X;
struct Y{
f(X* x){ cout<<x->a<<endl; }
}
class X{
int a;
public:
friend void Y::f(X*);
};
3、Declare a nested struture as a friend:当B是A的内嵌类时,A可以访问B中的全体数据成员,但反之却不行;可以将B声明为A的friend,使B可以访问A的全体数据成员
class Holder{
enum{ sz=100 };
int a[sz];
public:
class iterator;
friend iterator;
}
4、Object layout
Access block:由public、private、protected分出的block
同一access block中的变量在内存中连续存放;但不同block并不一定按照声明顺序存放在内存中
Chapter6: Initialzation & Cleanup
1、C结构体中,用户必须自己显式地调用初始化和清除函数;C++给类定义的Constructor和Destructor能自动或隐式地被调用
struct X{ //C结构体 class Y{ //C++类
public: public:
void initialize(); Y(); //Constructor
void clearup(); ~Y(); //Destructor
}; };
2、Constructor:类中一个特殊的成员函数(须声明为public)
当一个类对象被定义时,Constructor会自动被调用;
当Constructor被定义了以后,类对象的初始化方法是确定和固定的(指初始化传入的argument)
Constructor的名字与类的名字相同,这让编译器知道它是Construtcor且避免名字冲突
Constructor可能会有argument,但没有return value
3、Desrtuctor:类中另一个特殊的成名函数(须声明为public)
目的:实现一个类对象的自动清除
Destructor的名字格式:~class_name
Destructor没有argument和return value
当离开了作用域时,类对象Destructor自动调用完成清除
当指向类对象的指针被delete时,Destructor会默认调用清除对象
int main(){
Y y1; //Constructor called here
Y* py=new Y; //Constructor called here
delete py; //Destructor for the object py point to called here
!y1.~Y(); //显示调用Destructor是不被允许的
}//Destructor for y1 called here
4、Elimination of the definition block
C++中当我们定义一个类对象时,同时需要对它进行初始化;但有些类对象的初始化参数并不能在函数入口处就获得,因此C++中允许defining object on the fly
5、Aggregate initialization:
int a[5]={1,2,3,4,5}
int a[5]={0};
int c[ ]={1,2,3,4};
for (int i=0; i< sizeof c / sizeof *c; i++)
...
initialization of structures
initializaiton of objects with Constructors
6、Default constructor
只要类中已经定义了Constructor,编译器就不会使用default constructor
仅当类中没有定义Constructor,编译器会自动合成一个default constructor
default constructor只能完成“很少”的事情
Chapter7: Function Overloading & Default Arguments
1、Function Overloading
相同的函数名有不同的参数列表:
print(int* a)
print(float* f)
print(double* d)
编译器中对于函数重载的函数名声明:
_print_int
_print_float
_print_double
C++不能对函数返回值进行重载
2、Union in C++:union中的对象共用一块内存空间
class SuperVar {
enum { character, integer, floating_point
} vartype;
union { // Anonymous union
char c;
int i;
float f;
};
public:
SuperVar(char ch) {
vartype = character;
c = ch;
}
SuperVar(int ii) {
vartype = integer;
i = ii;
}
SuperVar(float ff) {
vartype = floating_point;
f = ff;
}
};
3、Default argument
目的:有些函数有许多参数且部分参数有一些典型或常用值;用户在调用函数时,通常会忽略这些参数,但在必要的时候能够传入参数
void preemphsize(float* sbuff, float coeff=0.95){
...
}
int main(){
float f=0.5;
preemphsize(&f);
Preemphsize(&f, 0.85);
}
4、More about default argument
只有尾部的参数可以有默认值:
int fun(int i, float f=1.2, double d=4.5, char c=‘a’ ) {...}
!int fun(int i, float f=1.2, double d, char c=‘a’) {...} // wrong!
类似的在调用时:
fun(i, 2.3);
!fun(i, , ,‘b’); // wrong!
5、Choosing overloading or default argument
原则:default argument可以被overloading替换
某些函数不适合使用default argument:abs(int),abs(float),abs(double)
如果函数由于default argument实现会出现分支,则使用overloading
6、Placeholder argument
In declaration: void f(int x, int, float);
or: void f(int x, int=0, float=12.3 );
In definition:
void f(int x, int, float ) { ... }
Chapter8: Constants
1、C中的#define与C++中的constants
#define的缺点:no type checking
constants in C++:a variable but its value can not be changed
const int size=10;
const double PI=3.14159
使用constants的优点:避免无意中改变的constant的值;使代码更具可读性
大多数情况下C++中不会为constants分配内存
2、为constants分配内存的情况
显式或隐式地引用了constant的地址(隐式:将constant作为reference参数)
constant存在于复杂的结构体中
在constant前加了extern
3、Constants for aggregates
aggregates中constant的内存会被分配,但constant的值在编译阶段是无效的
const int a[]={1,2,3,4};
!float[a[3]]; //illegal
struct S{ int i,j };
const S s[]={{1,2},{3,4}};
!float[s[0].i] //illegal
4、C++中constant默认为internal linkage,而C中默认为external linkage(编译阶段只能进行internal linkage)
const int size=100;
double d[size];
上面代码在C++编译时正确的,而C中是错误的
5、Pointers and constants
指向的对象是constant:
const char* pc=“asdf”
!pc[3]=‘a’; //wrong
pc =“efgh”; //ok
point本身是constant:
char* const cp=“asdf”
cp [3]=‘a’; //ok
!cp=“efgh”; //wrong
指向的对象和point本身都是constant:
const char* const p=“asdf”;
!p[3]=‘a’;!p=“efgh”;
//both wrong
6、Constant pointers
non-constant pointer可以转化成constant pointer
constant pointer不可以转化成non-constant pointer
Temporaries:自动转化为constant
void t( int* ) { }
void u(const int* cip) {
!*cip = 2;
int i = *cip;
!int* ip2 = cip;
}
const char* v( ) {
return "result of function v()";
}
const int* const w( ) {
static int i;
return &i;
}
int main() {
int x = 0;
int* ip = &x;
const int* cip = &x;
t(ip);
!t(cip);
u(ip);
u(cip);
!char* cp = v( );
const char* ccp = v();
!int* ip2 = w();
const int* const ccip = w();
const int* cip2 = w();
!*w( ) = 1;
}
7、char*字符串的两种定义区别
char* cp1=“hello”;
char cp2[]=“hello”;
!cp1[1]=‘a’; //wrong,the char* cp1 point to is in static storage area
cp2[1]=‘a’; //ok,the char* cp2 point to is in the heep
8、Constant in class object
目的:用于实现类中的值替换
class X{
const int size;
public:
X();
...
};
有个类对象都有一个“size”,一但被初始化就不可改变;“size”不能在定义时被初始化(利用constructor initialization list对constant数据成员进行初始化)
X::X(int sz): size(sz){ ... }
constant数据成员必须在constructor initialization list中初始化,非constant数据成员可以在constructor initialization list中初始化
9、Constant for a class
Solution 1:
class Bunch{
enum{ size=100 };
int a[size];
};
Solution 2:
class Bunch{
static const int size=100;
int a[size];
};
10、Constant objects & Constant member functions:constant对象一但被初始化,其数据成员就不能更改,constant成员函数不能更改类对象的数据成员
更改类对象可能的方法:
public数据成员会被任何外部函数更改—>编译器会检查出来
任何数据成员都会被成员函数更改—>constant成员函数
constant member functions:
class X{
int x;
public:
void print()const{ }
};
函数中不会更改任何数据成员;函数中不会调用任何非constant member function;constructor和destructor都不能为constant member function
11、Bitwise and logical constant object
bitwise constant:对象的每个字节都不可更改
logical constant:对象语义上是常量,但数据成员可以更改
—>by cast(不推荐)
—>mutable data number
Solution 1(by cast):
class X{
int i;
public:
void f()const{
((X*)this)—>i++; //ok
(const_cast<X*>(this))—>i++;)
` }
};
Solution 2(mutable data member):
class X{
int i;
mutable int j;
public:
void f()const{
j++; //ok
}
};
1、利用vector模拟二维数组:
vector<vector<double>> v(m,vector<double>(n)) 是模拟一个含m个数组类型元素的数组,其中每个元素都是一个拥有n个double元素的数组
2、C++中可以随时定义变量;但C中应该在域内最开始定义
3、C++中常量定义:const int x=10,变量在定义时必须被初始化,编译阶段有type checking;C中常量定义:#define PI 31.4,编译阶段没有type checking,只是单纯的替换
4、assert(__condition__) 是一个宏,而不是函数
5、C++中的explicit cast:
static_cast<Typename T> (运用情况:castless conversion,narrowing conversion,conversion from void*)
const_cast<Typename T> (运用情况:conversion from const or volatile)
reinterpret_cast<Typename T> (运用情况:cast to a completely different meaning——most dangerous)
dynamic_cast<Typename T> (运用情况:for type-safe downcasting)
Chapter4: Data Abstraction
1、C与C++中类或结构体的区别:
C结构体:只是将数据成员分装在一起,对外部是完全可见的;用户必须自己定义初始化和清除函数;相关函数必须把要访问的结构体的指针传给函数;易造成结构体之间函数名冲突
C++类:将数据成员与成员函数封装在一起,对外部是部分可见的;通过构造函数和析构函数完成类的构建与清除;成员函数(非static)中有隐含的this指针,可直接访问数据成员,无需显式传递类对象指针;类之间函数名不会发生冲突
2、类对象的size不能为0:
class B{
void f(){ }
};
...
int main(){
B b;
double d; //&b and &d would be the same if the size of B is zero
}
3、C++头文件中structure,class重复声明是不被允许的 (使用preprocessor来解决这一问题)
#ifndef SIMPLE_H
#define SIMPLE_H
struct simple{
...
};
#endif
4、内嵌类或结构体:将相关元素封装在一起
class Stack{
struct Link{
...
}*head;
...
};
5、Global scope resolution:在成员函数中引用一个全局变量
int a;
void f(){ }
struct B{
int a;
void f(){
::f();
::a++;
a--;
}
};
Chapter5: Hiding the Implementation
1、Access control:C++通过public、private、protected等关键字实现类中数据成员对于外部的部分可见
public: 任何函数都可以访问
private: 只可以被成员函数访问
protected: 只可以被派生类和成员函数访问
2、friend关键字:friend函数可以访问类的全体数据成员
class X;
struct Y{
f(X* x){ cout<<x->a<<endl; }
}
class X{
int a;
public:
friend void Y::f(X*);
};
3、Declare a nested struture as a friend:当B是A的内嵌类时,A可以访问B中的全体数据成员,但反之却不行;可以将B声明为A的friend,使B可以访问A的全体数据成员
class Holder{
enum{ sz=100 };
int a[sz];
public:
class iterator;
friend iterator;
}
4、Object layout
Access block:由public、private、protected分出的block
同一access block中的变量在内存中连续存放;但不同block并不一定按照声明顺序存放在内存中
Chapter6: Initialzation & Cleanup
1、C结构体中,用户必须自己显式地调用初始化和清除函数;C++给类定义的Constructor和Destructor能自动或隐式地被调用
struct X{ //C结构体 class Y{ //C++类
public: public:
void initialize(); Y(); //Constructor
void clearup(); ~Y(); //Destructor
}; };
2、Constructor:类中一个特殊的成员函数(须声明为public)
当一个类对象被定义时,Constructor会自动被调用;
当Constructor被定义了以后,类对象的初始化方法是确定和固定的(指初始化传入的argument)
Constructor的名字与类的名字相同,这让编译器知道它是Construtcor且避免名字冲突
Constructor可能会有argument,但没有return value
3、Desrtuctor:类中另一个特殊的成名函数(须声明为public)
目的:实现一个类对象的自动清除
Destructor的名字格式:~class_name
Destructor没有argument和return value
当离开了作用域时,类对象Destructor自动调用完成清除
当指向类对象的指针被delete时,Destructor会默认调用清除对象
int main(){
Y y1; //Constructor called here
Y* py=new Y; //Constructor called here
delete py; //Destructor for the object py point to called here
!y1.~Y(); //显示调用Destructor是不被允许的
}//Destructor for y1 called here
4、Elimination of the definition block
C++中当我们定义一个类对象时,同时需要对它进行初始化;但有些类对象的初始化参数并不能在函数入口处就获得,因此C++中允许defining object on the fly
5、Aggregate initialization:
int a[5]={1,2,3,4,5}
int a[5]={0};
int c[ ]={1,2,3,4};
for (int i=0; i< sizeof c / sizeof *c; i++)
...
initialization of structures
initializaiton of objects with Constructors
6、Default constructor
只要类中已经定义了Constructor,编译器就不会使用default constructor
仅当类中没有定义Constructor,编译器会自动合成一个default constructor
default constructor只能完成“很少”的事情
Chapter7: Function Overloading & Default Arguments
1、Function Overloading
相同的函数名有不同的参数列表:
print(int* a)
print(float* f)
print(double* d)
编译器中对于函数重载的函数名声明:
_print_int
_print_float
_print_double
C++不能对函数返回值进行重载
2、Union in C++:union中的对象共用一块内存空间
class SuperVar {
enum { character, integer, floating_point
} vartype;
union { // Anonymous union
char c;
int i;
float f;
};
public:
SuperVar(char ch) {
vartype = character;
c = ch;
}
SuperVar(int ii) {
vartype = integer;
i = ii;
}
SuperVar(float ff) {
vartype = floating_point;
f = ff;
}
};
3、Default argument
目的:有些函数有许多参数且部分参数有一些典型或常用值;用户在调用函数时,通常会忽略这些参数,但在必要的时候能够传入参数
void preemphsize(float* sbuff, float coeff=0.95){
...
}
int main(){
float f=0.5;
preemphsize(&f);
Preemphsize(&f, 0.85);
}
4、More about default argument
只有尾部的参数可以有默认值:
int fun(int i, float f=1.2, double d=4.5, char c=‘a’ ) {...}
!int fun(int i, float f=1.2, double d, char c=‘a’) {...} // wrong!
类似的在调用时:
fun(i, 2.3);
!fun(i, , ,‘b’); // wrong!
5、Choosing overloading or default argument
原则:default argument可以被overloading替换
某些函数不适合使用default argument:abs(int),abs(float),abs(double)
如果函数由于default argument实现会出现分支,则使用overloading
6、Placeholder argument
In declaration: void f(int x, int, float);
or: void f(int x, int=0, float=12.3 );
In definition:
void f(int x, int, float ) { ... }
Chapter8: Constants
1、C中的#define与C++中的constants
#define的缺点:no type checking
constants in C++:a variable but its value can not be changed
const int size=10;
const double PI=3.14159
使用constants的优点:避免无意中改变的constant的值;使代码更具可读性
大多数情况下C++中不会为constants分配内存
2、为constants分配内存的情况
显式或隐式地引用了constant的地址(隐式:将constant作为reference参数)
constant存在于复杂的结构体中
在constant前加了extern
3、Constants for aggregates
aggregates中constant的内存会被分配,但constant的值在编译阶段是无效的
const int a[]={1,2,3,4};
!float[a[3]]; //illegal
struct S{ int i,j };
const S s[]={{1,2},{3,4}};
!float[s[0].i] //illegal
4、C++中constant默认为internal linkage,而C中默认为external linkage(编译阶段只能进行internal linkage)
const int size=100;
double d[size];
上面代码在C++编译时正确的,而C中是错误的
5、Pointers and constants
指向的对象是constant:
const char* pc=“asdf”
!pc[3]=‘a’; //wrong
pc =“efgh”; //ok
point本身是constant:
char* const cp=“asdf”
cp [3]=‘a’; //ok
!cp=“efgh”; //wrong
指向的对象和point本身都是constant:
const char* const p=“asdf”;
!p[3]=‘a’;!p=“efgh”;
//both wrong
6、Constant pointers
non-constant pointer可以转化成constant pointer
constant pointer不可以转化成non-constant pointer
Temporaries:自动转化为constant
void t( int* ) { }
void u(const int* cip) {
!*cip = 2;
int i = *cip;
!int* ip2 = cip;
}
const char* v( ) {
return "result of function v()";
}
const int* const w( ) {
static int i;
return &i;
}
int main() {
int x = 0;
int* ip = &x;
const int* cip = &x;
t(ip);
!t(cip);
u(ip);
u(cip);
!char* cp = v( );
const char* ccp = v();
!int* ip2 = w();
const int* const ccip = w();
const int* cip2 = w();
!*w( ) = 1;
}
7、char*字符串的两种定义区别
char* cp1=“hello”;
char cp2[]=“hello”;
!cp1[1]=‘a’; //wrong,the char* cp1 point to is in static storage area
cp2[1]=‘a’; //ok,the char* cp2 point to is in the heep
8、Constant in class object
目的:用于实现类中的值替换
class X{
const int size;
public:
X();
...
};
有个类对象都有一个“size”,一但被初始化就不可改变;“size”不能在定义时被初始化(利用constructor initialization list对constant数据成员进行初始化)
X::X(int sz): size(sz){ ... }
constant数据成员必须在constructor initialization list中初始化,非constant数据成员可以在constructor initialization list中初始化
9、Constant for a class
Solution 1:
class Bunch{
enum{ size=100 };
int a[size];
};
Solution 2:
class Bunch{
static const int size=100;
int a[size];
};
10、Constant objects & Constant member functions:constant对象一但被初始化,其数据成员就不能更改,constant成员函数不能更改类对象的数据成员
更改类对象可能的方法:
public数据成员会被任何外部函数更改—>编译器会检查出来
任何数据成员都会被成员函数更改—>constant成员函数
constant member functions:
class X{
int x;
public:
void print()const{ }
};
函数中不会更改任何数据成员;函数中不会调用任何非constant member function;constructor和destructor都不能为constant member function
11、Bitwise and logical constant object
bitwise constant:对象的每个字节都不可更改
logical constant:对象语义上是常量,但数据成员可以更改
—>by cast(不推荐)
—>mutable data number
Solution 1(by cast):
class X{
int i;
public:
void f()const{
((X*)this)—>i++; //ok
(const_cast<X*>(this))—>i++;)
` }
};
Solution 2(mutable data member):
class X{
int i;
mutable int j;
public:
void f()const{
j++; //ok
}
};
相关文章推荐
- C语言计算最大公约数
- C语言static
- 学习C++动态链接库基础知识 (主要关于QT项目)PART2
- boost::serialization学习笔记
- C++获取控制台输出
- C语言extern
- c/c++数组初始化误区
- C++关于二进制位操作小结
- LeetCode_Validate Binary Search Tree
- 黑马程序员-OC语言-函数和对象方法的区别(听课笔记)
- c++程序员经典面试题
- 黑马程序员-OC语言-#pragma mark指令的使用(听课笔记)
- C语言宏定义
- VC++ 自定义控件的建立及使用方法
- C++ CTreeview的checkbox使用方法
- c++正则表达式模板库GRETA的使用
- c++学习笔记4,调用派生类的顺序构造和析构函数(一个)
- VC++多线程编程
- 斐波那契数列-数组和递归-C语言
- (6)风色从零单排《C++ Primer》 结构体,头文件