some C++ summary
来源:互联网 发布:苹果mac激活时间查询 编辑:程序博客网 时间:2024/05/18 02:17
1, 头文件(包括.h和.hpp)里面有
#ifndef __SOMEFILE_H__ <--if not define
#define __SOMEFILE_H__
... ... //声明,定义
#endif
加入这些是防止头文件被重复include. 需要注意的是宏(__SOMEFILE_H__)在每个头文件里面要不同,所以一般而言是大写的文件名
当该头文件多次被包含的时候,第一次#ifndef为true,就会定义#define,以及定义里面的变量;第二次被包含的时候,判断ifndef为false,不进到里面去执行
.h一般是定义函数,类以及宏.如果定义某个变量,那么就会有重复定义的问题。如
三个文件,main.c, common.c以及common.h, 在common.h里面定义了char key;且main.c和common.c都include该.h文件。那么就会有重复定义的问题。
所以为了在头文件避免该问题,就加入#ifndef,#define和#endif.这样即使加入某些变量也不会有问题
2, .hpp
.hpp就是.h + .cpp, 将cpp的实现代码混入.h, 即定义和实现在同一个文件。
一些注意点:
1) 不能使用全局函数和全局对象。原因是.hpp可能会被多个文件include,这样会产生重复定义
2) 类之间不能循环调用,即A调用了B,B也调用了A
3) 不能使用静态变量。
原因是:如果.hpp含有类,这个类含有静态变量.因为静态变量属于类,不属于某个对象。静态变量不能直接初始化,其初始化是这样的:
class A
{
public:
static int i;
};
int A::i = 1;
且只能初始化一次,某个会有重复定义的错误
因此,如果在.hpp里面定义了含有静态变量的类,那么就要在该文件里面初始化。因为该hpp文件会被include多次,所以会执行初始化很多次
4) .h&.cpp可以使用usingnamespace std, .hpp不可以
所谓usingnamespace std:
C++标准库的所有标识符(cout,endl等)全部放在名称为std的namespace之下
所以有两种方式来调用:
a) std::cout<<std::hex<<3.4<<std::endl;
b) using namespace std
cout<<hex<<3.4<<endl;
c) using std::cout;using std::hex;using std::endl;
cout<<hex<<3.4<<endl;
3, this指针
this只能在成员函数中使用
全局函数,静态函数都不能使用this
this在成员函数的开始前构造的,在成员的结束后清除
4, extern
extern有两个作用:
1) 与”C”一起用。如extern “C” void fun(int a, int b);编译就会按照c语言的规则编译,否则因为C++支持重载,其名字会编译为fun@abc_int_int之类的乱码,这样函数就会找不到
2) 不与”C”一起用,用来修饰变量或函数的时候,表明该函数或变量在模块也可以用。修饰函数与变量实际上是一样的
5, const
1)const 与define相比,具有数据类型,编译器会对其进行检查如byte不能超过FF,但是define直接进行替换,不检查
2)不能在类声明中初始化const成员,如
class A
{
const int SIZE =100; <--wrong
int array[SIZE];
}
而应该在构造函数的初始化表的时候进行
class A
{
A(int size); //构造函数
const int SIZE;
}
A::A(intsize):SIZE(size) //构造函数的初始化表
{
...
}
A a(100) //size =100
3) char const *p;//*p is const, p is changable
char*const p; //p is const,*p is changeable
intconst *p1,p2 //p2是const,与最近的一个结合
6, static
1) 在函数内,静态的变量维持其值不变
2) 在模块内,函数外,在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
8, inline
本来是要调用函数的,需要频繁的使用stack的。现在用上了inline之后,是直接替换,不是调用。可以节省栈空间。
注意的是inline只适用简单的函数.根据google c++ coding style guideline, inline的函数不能超过10行
9, 变量声明与变量定义
变量定义是指数据类型 + 变量名称,编译器分配内存
变量声明是指extern 数据类型 + 变量名称,编译器不分配内存
12, 内存分为stack,heap,全局区(或称静态区)(static以及全局变量),常量区(string)和代码区
NOTE:在全局区的变量的默认值为0
13, 颠倒一个字节, 如该字节原来的位数是1 2 3 4 5 6 7 8, -->8 7 6 5 4 3 2 1
unsigned char reverse8( unsigned charc )
{
c = ( c & 0x55 ) << 1| ( c & 0xAA ) >> 1;
c = ( c & 0x33 ) << 2| ( c & 0xCC ) >> 2;
c = ( c & 0x0F ) << 4| ( c & 0xF0 ) >> 4;
return c;
}
(1)2个2个为一组,交换前一半和后一半, 变成: 2 1 4 3 6 5 8 7
(2)4个4个为一组,交换前一半和后一半, 变成: 4 3 2 1 8 7 6 5
(3)再8个为一组,交换前一半和后一半, 变成: 8 7 6 5 4 3 2 1
14, C++四种强制转换
const_cast: 消除const标志
reinterpret_cast: 任意两个类型的指针之间可以转换,一般用于底层,导致implement-dependent
static_cast: 最接近C的风格
dynamic_cast:有两个条件,1),数据类型为指针或引用,2)要求基类是多态的(含有虚函数)
#include <iostream>
class CBase {};
class CDerived: public: CBase {};
int main()
{
CBaseb;
CDerived *d;
d =dynamic_cast<CDerived *>(&b) <--wrong. CBase不含有需函数
}
可以将类的定义改为
class CBase {virtual void dummy(){} }
15,引用与取地址的区别: 引用的格式一定是type & variable; 如int &n = m; void fun(int&n, int m);
16,delete/free之后必须将指针置为null
17,eat up memory
int main()
{
char *p = NULL;
while (TRUE)
{
p = new float[10000];
if(p == NULL)
exit(1); //exit(0)正常退出,exit(1)表示非正常退出,是会影响os log的
}
return 0;
}
eat up cpu
int main()
{
while(1)
{ };
return 0;
}
18,为何malloc/free需要:C语言只支持malloc/free,不支持new/delete
为何new/delete需要: C++要求分配内存的同时执行构造函数,释放内粗的同时执行析构函数
19,char *p[3] -->括号的优先级高于*,所以p先与[结合,所以p是一个数组,数组元素皆为char *
char (*p)[3] -->p是一个指针,指向一个数组,其元素为char
20,char a[20];
int *p = (int*)a;
p++; --> sizeof(int) + a; //sizeof的时候要去掉一个*
char a[20];
char *p = a;
char **ptr = &p; //实际上ptr = p, &p = char**(&p) = char **ptr, àptr = &p;
ptr ++; //相当于&p+sizeof(char*) (将ptr的类型去掉一个*) sizeof(char*)=4, &p的值未知
21,thread & process
简而言之,一个程序至少有一个进程,一个进程至少有一个线程
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉
线程之间用mutex
进程之间用critical section
22, 重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中);(不能一个全局函数,一个成员函数)
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
23,成员初始化列表
classMemberInitializationList
{
private:
int i;
int j;
public:
MemberInitializationList(int val) :j(val), i(j) //j(val), i(j)就是所谓的成员初始化列表,根据变量定义的顺序,先i后j, i=j, j=val
{
}
inline void printinfo()
{
cout << "i = " << i << ", j = " <<j << endl;
}
};
int main(void)
{
MemberInitializationList MIL(10);
MIL.printInfo();
return 0;
}
i=10,j=10
初始化列表也可以表示为.据说用初始化列表的方式效率比较高,因为没有用临时变量
MemberInitializationList(intval)
{
j=val;
i=j;
}
24sizeof
sizeof(a)-->sizeof(type of a)
so char *p; sizeof(p) = sizeof(char *)=4;
25, 基类的构造函数、析构函数、赋值函数都不能被派生类继承
27, 继承规则应当是:若在逻辑上B 是A 的“一种”,并且A 的所有功
能和属性对B 而言都有意义,则允许B 继承A 的功能和属性
比如鸵鸟能否从鸟类继承?鸟飞的属性对于鸵鸟无意义,因此不能继承
28, 继承和派生:
继承从子类的角度看。派生从基类的角度看
- some C++ summary
- some C++ summary 2
- some java summary
- some summary of basic linux
- C++-Class Summary
- Summary on 20080626: some difference between JDBC transaction and JTA
- Some C Learning Notes
- Some Methods (C#)
- Some interesting C problems
- Some simple c program
- [C++] Some hints
- C/C++ Summary at USC
- Unit Test summary for C
- 【LeetCode-228】Summary Ranges(C++)
- Some essential problems in C
- Some Tips In Object C
- Some Tips In Object C
- Some Tips In Object C
- HDU 2955 Robberies(经典01背包概率问题)
- OpenCV单kinect多帧静止场景的深度图像去噪
- ip2long long2ip
- webbrowser 接口简介
- IR领域标准
- some C++ summary
- 数字转化成特殊字符的 方法 !
- Debian下MySQL安装的问题
- RAC OEM 打开无法显示CPU情况 的解决过程
- 一步步构建大型网站架构
- 定位激活(webbrowser)
- sed 用法介绍
- ubuntu 下jdk 安装
- teaklite DSP汇编编程