- 命名规则
- 成员函数
- 构造函数
- 析构函数
命名规则
类名命名: 一般用名词形式
例如:
Circle
MemoryPool
GoodObject
成员函数命名: 一般用动词形式
例如:
Open
Close
SendMessage
成员变量:小写开头
例如:
m_number
m_server
m_port
m_buffer
成员函数
定义在class
内的函数,称为该类的成员函数
class Object
{
public:
int x;
int y;
void Test()
{
printf("hello,world!\n");
}
};
成员函数的访问:也是使用.
号或 ->
Object obj;
obj.Test(); // 点号 .
Object* p = &obj;
p->Test(); // 箭头 ->
被public修饰的可以被外部访问,被private修饰的则不能被外部访问
class Object
{
public:
int x;
int y;
void Test()
{
printf("hello,world!\n");
}
private:
void Test2() // 该函数被private修饰,不能被外部访问
{
printf("I am a private function!\n");
}
};
函数重载
- 函数名相同、函数参数个数、类型不同、参数顺序不同
- ⚠️ 返回值类型与函数重载无关
本质
采用了name mangling或者叫name decoration技术
✅ C++编译器默认会对符号名(比如函数名)进行改编、修饰、有些地方翻译为“命名倾轧”
// display_int
void display(int a) {
}
// display_long
void display(long a) {
}
// display_double
void display(double a) {
}
看着函数名一样,但是在编译时对函数名进行name mangling技术会变成类似上面那样
构造函数 (constructor)
构造函数:对象被创建时被调用
构造函数是类的一种特殊的成员函数:
- 函数名与类名必须相同
- 没有返回值
例如
class Circle
{
...
public:
// 不需要传参的构造函数,称为默认构造函数
Circle ()
{
x = y = 0;
radius = 1;
}
// 构造函数可以带参数,也可以重载
Circle(int x, int y, int r)
{
this->x = x;
this->y = y;
this->radius = r;
}
};
构造函数和普通成员函数不一样,一般不显式调用
。
在创建一个对象时,构造函数被自动调用。(由编译器完成)
// 例如:
// 它们在内部实质上是分别调用了不同的构造函数,但是表面上没有这个函数调用过程
Circle a;
Circle b(1,1, 4);
默认构造函数很重要。如果一个类没有默认构造函数,则无法构造数组
一般都要给类定义一个默认构造参数,以方便使用
// 例如:
class Object
{
public:
Object(int x){}
};
Object objs[4]; // 错误❌
如果一个类没有写任何构造函数,则编译器隐含地生成为其添加一个
// 相当于添加了
Object::Object()
{
}
注意:只有当你没有写构造函数的时候,才给隐含地加一个构造函数
。一旦你写了一个构造函数,它就不给你加了
析构函数(destructor)
析构函数:对象被销毁时被调用
析构函数也不是普通的函数
- 名称固定:类名前加上波浪线~
- 没有返回值
- 不能带参数
注:析构函数只能有一个,不允许重载
class Object
{
public:
~Object()
{
}
};
析构函数从不显式地调用,而是对象被销毁之时
被编译器自动地调用
析构函数的作用,就是对象在销毁之前,做一个清理善后工作,比如,申请来的内存要释放掉,打开的文件FILE*
要关闭掉...
成员的初始化与析构
如果成员变量本身也是 class类型的情况:
-
当对象被构造时,成员变量也被构造(成员变量的构造函数被调用)
-
当对象被析构时,成员变量也被析构(成员变量的析构函数被调用)
结论:
一、构造的时候
成员被依次构造: 从前到后
先执行成员的构造函数,再执行自己的构造函数
二、析构的时候
成员被依次析构: 从后到前
先执行自己的析构函数,再执行成员的析构
初始化列表
// 方法一 : 初始化的方式
class Object
{
public:
Object() // 已经对 m_child进行了构造
{
m_child.x = 1;
m_child.y = 2; // 又多了一步操作
}
};
// 方法二 赋值方式
class Object
{
public:
Object() : m_child(1,2)
{
}
};
第一种方式,性能上更好,所以推荐第一种方式
网友评论