您的位置:首页 > 编程语言 > C语言/C++

《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

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: