C++ 函数

2021-12-20  本文已影响0人  我阿郑

命名规则

类名命名: 一般用名词形式

例如:
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)
    {
    }
};

第一种方式,性能上更好,所以推荐第一种方式

上一篇 下一篇

猜你喜欢

热点阅读