c++学习笔记之类

c++学习笔记系列:http://blog.csdn.net/column/details/17301.html


1、预处理器封套

#ifndef XXX_H
#define XXX_H
...
class xxx{
...
}
...
#endif
如果没有文件包含此头文件,XXX_H被定义幷包含这个头文件;如果已经包含,则不再定义和包含。
为了防止多次包含同一个头文件,尤其包含套包含的时候。注意命名要大写和下划线

2、对象的sizeof

sizeof一个对象得到的是所有数据成员的大小。
因为函数不存储在对象中,而是由编译器创建独立于所有对象的函数副本,所有对象共享函数副本

3、访问对象数据成员和成员函数

对象名或对象引用的情况      a.b          a.b()
对象指针的情况        aPtr -> b           aPtr -> b()

4、工具函数

工具函数即private函数

5、析构函数

~类名()              在对象被撤销时被调用,某种意义上是与构造函数互补。
class Time{
     Time(...){...}
     ~Time(){...}
}
注意:不接收任何参数,不返回任何参数,void也不行。
          一个类只能有一个析构函数,不允许重载

6、对象传参

当对象作为参数或返回值时是传值参数,即传的是拷贝
所以当要使用真正对象需要传引用或指针。

7、const对象\函数

声明对象(注意位置):void name() const {....}
对象声明const不能被修改,不能调用非const的成员函数。
成员函数声明const不能修改对象,同样不能调用非const的成员函数。
(1)可以对const成员函数进行非const重载。编译器根据对象性质选择相应函数,const对象调用const函数;非const对象调用非const函数
(2)构造、析构函数不能声明const。

8、成员初始化器

int count;
const in num;
Time(int i, int j):count(i),num(j){...}
所有数据成员都可以用成员初始化器来初始化,如上面的形式。
但是const数据成员和引用的数据成员必须使用成员初始化器进行初始化,不能通过赋值初始化。
(1)成员初始化器在构造函数体执行前执行
(2)建议将所有不修改对象的函数声明为const。

9、组成

即数据成员是一个其他类的对象。
如果构造函数没有初始化某个成员,那么会隐式的调用该成员的默认构造函数。如果该成员的类没有默认构造函数,编译报错

10、friend函数和类(友元)

class A{
     friend class B;
     friend void b(...);
}
友元可以访问原类中的非public成员和函数。
(1)友元关系不传递,不对称。
(2)友元函数不是成员函数
(3)友元最好在数据成员及函数之前声明。
(4)友元模板类或模板函数的情况,需要提前定义,否则报错,如:
template<typename T> class B;
class A{
     friend class<T> B;
}
(5)友元是非模板类的成员函数,也需要提前定义

10、this指针

因为是指针,所以:this -> x  或  (*this) .x

11、动态内存管理(new\delete)

Time time; 或 int num[24]; 这样在定义时需要将所有内存分配(所有成员内存或所有元素内存),即使未使用到,且不能改变。
使用动态内存管理实际上是在自由存储区分配内存区域,通过delete释放。
Time *timePtr = new Time(....);
delete timePtr;
int *numsPtr = new int[24];
delete [] numsPtr;
(1)释放时先调用析构函数,再回收内存。数组释放时不加“[]”只调用第一个元素的析构函数。
(2)不释放会造成内存泄漏
(3)在编译时创建数组,大小必须用常量;而动态分配是可以使用任何表达式,如new int[a + b];
(4)动态分配一个对象数组时,会使用对象的默认构造函数初始化
(5)delete之后最好将指针设为0,如numsPtr=0。因为回收后内存空间中的信息还在,只是没有关系了,如果不注意访问了,会导致极端诡异无法复现的问题
(6)尤其注意循环中要使用new,否则会出错,如下:
for (int i = 0; i < 5; i++) {
     Node<int> node(i);
     Node<int> *ptr = &node;
}

运行时会发现每次循环ptr指针指向的地址是不变的,也就是说所有的循环一致用一个Node对象而不是每次新建,这样会导致逻辑错误。改成new动态分配后,每次循环都是新的对象。

12、static

static数据成员只能被初始化一次。
int或枚举类型的const static数据成员可以在类定义中初始化;所有其他类型的数据成员必须在文件作用域(类定义外)定义并初始化。
xxx.h
class{
     ...
private:
     static int a;
     ...
}

xxx.cpp
...
int a = 1;
...

(1)在.cpp文件中定义初始化static数据成员时不能声明static,应该在.h中声明为static
(2)如果成员是对象且有默认构造函数,可以不初始化。
(3)public static数据成员在类外部使用:没有任何对象时Time::cout;有对象时time.count。
(4)在static函数中不能使用this,否则编译错误。static函数不能被声明称const


13、代理类

使用头文件虽然可以隐藏实现细节,但是依然暴露private数据成员或函数。
使用代理类,只有一个private成员,即被代理类的对象指针。

发布了106 篇原创文章 · 获赞 30 · 访问量 26万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章