c和c++部分知识点:
###
i++ 与 ++i 区别
内建数据类型,效率没有区别;自定义数据类型的情况,++i效率较高,原因++i返回对象的引用,而i++返回对象的值,产生较大复制开销。
i++操作符重载如下:
A operator++(int) {
A temp(num);
num++;
return temp;
}
++i操作符重载如下:
A& operator++() {
num++;
return *this;
}
###
空类编译器会安插一个char,因此sizeof空类为1字节;一个多重继承两个空类的空类依然为1字节;虚继承一个空类则子类有个指针指向基类,则大小为4字节,虚继承两个空类则为8.
###
sizeof为操作符,编译时处理,表示能容纳最大字节;strlen为函数,运行时表示字符串长度,并且不包括'\0'.
###
内联是以代码膨胀为代价的,省去函数调用,提高效率,如果函数内部运行时间远大函数调用时,则提高效率有限。
#33
常量指针,指向常量的指针;指针常量,首先是常量,再是指针,指针常量就是不能修改这个指针所指向的地址,一开始初始化指向哪儿,就只能指哪儿,像数组名。
#33
char * const p1 ; //指针常量,自身不能修改,所指内容可以被修改。
char const * p2 ; //
const char *p3 ; // p2,p3都是常量指针,本身可以修改,所指内容不能修改。
const char *const p4; // 本身是常量,并且所指内容也不可被修改。
#33
class MyClass
{
public:
MyClass(int data)
{
m_data = data;
}
void Print()
{
//std::cout << m_data << std::endl; //注释掉此行,传进来的对象this指针实际上没有任何用处,这样的函数其特征与全局函数并没有区别。
std::cout << "hello!" << std::endl;
}
private:
int m_data;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyClass *pMyClass = new MyClass(1);
pMyClass->Print();
pMyClass[0].Print();
pMyClass[1].Print();
pMyClass[10000].Print();
return 0;
}
注掉结果:
hello!
hello!
hello!
hello!
开启结果:
1
hello!
1
hello!
-33686019
hello!
访问违规段错误
#33
指针与句柄
指针指向一数据在内存中的地址,windows并不希望一般程序修改其内部数据结构,这不安全,所以windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄,句柄是一种指向指针的指针。
句柄所指的可以是一个很复杂的结构,并且很有可能是与系统有关的,这个句柄的某一项是与系统进行交互的。
指针也可以指向一个复杂的结构,但是通常是由用户定义的。
#33
const_cast: 去掉const限制
dynamic_cast: 判断在运行是所指向对象的确切类型,限于对象指针的类型转换,而非对象变量。
reinterpret_cast: 将一个指针转换成其他类型的指针;
static_cast: 它能在相关的对象和指针类型之间进行类型转换。
#33
A a; //声明一个无参对象不能用A a();
#33
覆盖,重写,重载,隐藏,多态
首先,覆盖也称重写,英文override
特点:
1. 指不同作用域中(派生类和基类)同名函数的定义 2. 函数名、参数均完全相同 3. 基类对应方法前有 virtual,即被声明为虚函数
作用:
基类指针和引用在调用对应方法时,根据所指对象类型实现动态绑定。
其次,重载(overload)
特点:
1. 作用域,同一类中 2. 函数名相同,但是参数类型、个数等不完全相同
作用:
同一方法,根据传递消息的不同(类型或个数),产生不同的动作(相同方法名,实现不同)。
隐藏(遮蔽)
特点:
不同作用域,基类和派生之间
分两种情形:
一、 基类和派生类函数名相同,但是参数列表不同,不同有无virtual,基类函数在派生类中被隐藏,派生类只能调用新的方法,不能调用已被隐藏的基类方法(不同于重载,作用域不同)
二、 基类与派生类同名,同参,但基类函数无virtual,同样派生类中同样隐藏基类的同名同参函数(不同于覆盖,无virtual)
#33
模板会导致代码膨胀,即二进制代码臃肿而松散,会严重影响程序的运行效率。解决方法是把与参数无关的代码分离出来。