C++
● ::
::是作用域操作符,在使用命名空间是经常使用到::,该命名空间就是一个作用域。在定义类的成员函数时也经常用到::,表示类的作用域。
● C++版本的C标准库
C标准库的名字:name.h
对应的C++标准库为cname
cname文件中定义的名字在std空间中,而如果使用C标准库的头文件,名字不属于std
● 声明、定义
只声明不定义,使用extern关键字
extern int i; //只声明,未定义
int j; //声明,并定义
● 多态
多个不同类的对象对同一个方法的调用产生不同的结果。
多态有三种实现方式:函数重载、运算符重载、虚函数。
多态分编译时的多态和运行时的多态。
覆盖:基类中有个非虚函数,子类中也有个同名,同参的非虚函数。
重载:函数名相同,参数类型、个数不同
参考:
http://www.cnblogs.com/cxq0017/p/6074247.html
http://blog.csdn.net/jixianghahaxiao/article/details/45645035
● 数组指针
int (*p)[5]; 指向长度为5的数组的指针
int (*p)[5] = a[3][5]
p++,移动了一个一维数组
指针相减,返回的是实例的个数,而不是地址的差值
char a[5]={'A','B','C','D'};
char (*p3)[5] = &a; //正确
● new/delete
new/delete不是函数,是关键字;
下面几个是C++标准库函数
void *operator new(size_t); //allocate an object
void *operator delete(void *); //free an object
void *operator new[](size_t); //allocate an array
void *operator delete[](void *); //free an array
new申请内存的步骤:
1.调用operator new库函数申请空间,但未初始化
2.调用类的构造函数,对上一步申请的空间进行初始化(如果不是类类型,则不会初始化)
3. 返回对象的地址
delete步骤:
1. 调用类的析构函数(如若是类类型)
2. 调用operator delete函数,释放内存
new [] 会多分配4字节的内存来记录分配了多少个对象

delete []释放内存的时候,会调用operator delete[]函数
参考:http://blog.csdn.net/hazir/article/details/21413833
● static关键字
static分为面向过程和面向对象两种用法。
面向过程:
static全局变量:存储在全局数据区;如果未初始化,则默认初始化为0;不可被其他文件的代码访问,即使他文件用extern关键字(但是通过include包含该源文件,则,可以通过编译);
static局部变量:存储在全局数据区;如果未初始化,则默认初始化为0;作用域为该函数;
static函数:不可被其他文件的代码访问;
面向对象:
static变量:属于类,所有对象共享;存储在全局数据区,不能再类里初始化;可以在其他函数里引用(前提是符合public、protected、private访问控制);两种访问方式:<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
class load
{
public:
load()
{
this->date = 2017;
}
static int sum;
int get_interest();
int get_date();
static int get_sum_static();
static int get_date_static();
private:
int date;
static int interest;
};
int load::interest = 1;
int load::sum = 10;
int load::get_interest()
{
return interest;
}
int load::get_date()
{
return this->date;
}
int load::get_sum_static()
{
return load::sum; //OK
}
int load::get_date_static()
{
return 0;
//return this->date; //出错,static函数不存在this指针
}
int main()
{
load ld;
cout << load::sum << endl;
cout << ld.sum << endl;
//cout << load::interest << endl; //编译出错,
//cout << ld.interest << endl; //编译出错,
cout << ld.get_interest() << endl;
cout << ld.get_date() << endl;
cout << ld.get_sum_static() << endl;
cout << ld.get_date_static() << endl;
return 0;
}
static成员函数:属于类;可以访问其他static成员函数和static成员变量,但不可访问非static函数和变量(由于没有this指针);非static成员函数可以访问static成员函数和static成员变量;调用方式:<类名>::<静态成员函数名>,或<对象>.<静态成员函数名>,或<对象指针>-><静态成员函数名>
● 对象作为参数
参数传递对象的时候,会产生一个const类型的临时对象。如果函数的参数声明为非const,会报错,例如:
string foo( );
void bar(string&s)
// 那么下面的表达式将是非法的:
bar(foo( ));
bar("hello world");
● 函数返回引用
1. 函数不可返回局部变量的引用,因为函数返回时,局部变量会消失,引用指向的变量为空。
2. 尽量避免返回new申请的对象,因为这样很可能会引起内存泄漏,虽然这样做是合 法的。
例如:
string&
foo()
{
string* str = new
string("abc");
return *str;
}
string str = foo(); //内存泄漏,str得到的是一个副本,foo申请的内存无法释放(没有变 量指向它)。下面的做法可以解决这个问题(麻烦):
string&
tmp = foo();
string str = tmp;
delete &tmp;
但是下面的做法,不知不觉就造成了内存泄漏:
string str = "hello" + foo();
● 拷贝构造函数
默认拷贝构造函数是,类中没有明确定义,编译器自动生成的拷贝构造函数。
class man
{
private:
int age;
public:
man( int age )
{
this->age = age;
}
man( const man& m ) //拷贝构造函数
{
age = m.age;
}
void print()
{
cout << age << endl;
}
};
拷贝构造函数的参数一定要定义为常引用,例如const man& m,否则会编译出错。
● 拷贝构造函数调用的时机
1. 以值传递的方式作为参数:func( man m);
2. 以值传递的方式从函数返回:func() { return m}
3. 赋值、初始化:man m2 = m
● 浅拷贝
浅拷贝是指对对象中的成员执行简单的复制。例如下面的rect2,它的p成员与renct的p指向同一个地址。这样,当执行对象销毁的时候,rect1和rect2都会对p进行析构,因此会发生错误。正确的做法是,两个对象的p成员的地址不同,但地址中的值相同。因此,需要深拷贝。
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
~Rect() // 析构函数,释放动态分配的空间
{
if(p != NULL)
{
delete p;
}
}
private:
int width;
int height;
int *p; // 一指针成员
};
int main()
{
Rect rect1;
Rect rect2(rect1); // 复制对象
return 0;
}
● 深拷贝
对于动态成员,应该重新分配内存空间,因此需要定义拷贝构造函数:
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
~Rect() // 析构函数,释放动态分配的空间:
{
if(p != NULL)
{
delete p;
}
}
Rect( const Rect & r) // 拷贝构造函数
{
p = new int( *( r.p ) );
}
private:
int width;
int height;
int *p; // 一指针成员
};
● 防止调用默认拷贝函数
定义一个私有的拷贝函数,当用户试图值传递类对象是会报错:
private:
Rect (const Rect & R); //拷贝构造,只是声明
func ( rect1); //报错
拷贝构造函数,参考:http://blog.csdn.net/lwbeyond/article/details/6202256/
浙公网安备 33010602011771号