C++ 关键字

static关键字

  • 修饰局部变量
    static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期和村工序相同,在main函数之前初始化,在程序退出时销毁。(无论时局部静态还是全局静态)
  • 修饰全局变量
    全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被包含该定义的文件访问(即改变了作用域)
  • 修饰函数
    static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,生命和定义需要放在同一个文件夹中。
  • 修饰成员变量
    用static修饰的数据成员使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象,所有的对象都只维持同一个示例。因此,static成员必须在类外进行初始化(初始化格式: int base::var = 10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化。
  • 修饰成员函数
    用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量。静态成员是可以独立访问的,也就是说,无须创建人换个对象实例就可以访问。例如可以封装某些算法,比如数学函数,如sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);还可以实现某些特殊的设计模式:如Singleton

const关键字

  • 定义变量为只读变量,不可修改
  • 修饰函数的参数和返回值(后者应用比较少,一般为值传递)
  • constant成员函数(只需要在成员函数最后加上const,如char get() const;)可以访问const成员变量和非const成员变量,但是不能修改任何变量。在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能将该成员函数声明为const成员函数。
  • const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数,即对于class A,有const A a;那么a只能访问A的const成员函数。对于A b;b可以访问任何成员函数。

mutable关键字

在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。

typedef关键字

  • 提高了可移植性
  • 简单复杂的类型声明,提高编码效率
  • 解释数据类型的作用

extern关键字

  • 与"C"一起连用的时候,如 extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数的时候按着C的规则区翻译,而不是C++(这与C++的重载有关,C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库中的名字与C语言不同)
  • 不与"C"在一起修饰变量和函数时,如exturn int g_Int;它在作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用。记住它是一个声明而不是定义!也就是说B模块(编译单元)要时引用A模块中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数或变量。

explicit关键字

C++中的explicit关键字只能用于修饰只有一个参数的类构造函数,它的作用是表明该构造函数是显示的,,而非隐式的,,跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。explicit关键字的作用就是防止类构造函数的隐式自动转换。

class Test1{
public:
    Test1(int num) {
        m_num = num;    
    } // 普通构造函数
private:
    int m_num;
};

class Test2{
public:
    explicit Test2(int num) {
        m_num = num;    
    } // 普通构造函数
private:
    int m_num;
};

int main() {
    Test1 t1 = 12; // 隐式调用其构造函数,成功
    Test2 t2 = 12; // 编译错误,不能隐式调用其构造函数
    Test2 t3(12); // 显示调用成功
    return 0;
}

virtual关键字

  • C++中的函数调用默认不使用动态绑定。要触发动态绑定,必须满足两个条件:
    1. 指定该函数为虚函数
    2. 通过基类类型的引用或指针调用
      由此可见,virtual主要作用就是实现动态绑定
  • 友元函数、构造函数、static静态函数不能用virtual修饰
  • 普通成员函数、析构函数可以用virtual修饰
  • 只要基类中的函数定义了virtual,集成类的该函数也具有virtual属性
  • 析构函数最好写成virtual(通过虚函数表,编译器知道要去执行基类的析构函数,执行完派生类的析构函数后,按照C++的内部机制紧接着区执行基类的析构函数)
class Test1
{
public:
    Test1() { printf("Test1()\n"); }
    ~Test1() { printf("~Test1()\n"); }
}
class Test2
{
public:
    Test2() { printf("Test2()\n"); }
    ~Test2() { printf("~Test2()\n"); }
}

class Test3
{
public:
    Test3() { printf("Test3()\n"); }
    virtual ~Test3() { printf("~Test3()\n"); }
}
class Test4
{
public:
    Test4() { printf("Test4()\n"); }
    ~Test4() { printf("~Test4()\n"); }
}

int main{
    Test1 t1 = new Test2();
    delete t1;
 
    Test1 t3 = new Test3();
    delete t3;

    // 运行结果
    /**
    Test1()
    Test2()
    ~Test1()

    Test3()
    Test4()
    ~Test4()
    ~Test3()
    **/
}
posted @ 2020-04-19 14:50  ghx_kevin  阅读(139)  评论(0编辑  收藏  举报