C++中的const、static和extern

1. const

  1. 常量变量
    const 类型说明符 变量名
const int num = 1; // 在定义num后,不能对该变量进行修改
  1. 常引用
    const 类型说明符 &引用名
const int &num = a;
num = 1;   //错误
a = 1; // 正确
/* 注意:
    在什么时候使用常引用:如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在
    函数中被改变,就应使用常引用
*/
  1. 常对象
    类名 const 对象名 或者 const 类名 对象名
class A
{
    private:
      int a;
    public:
      A(int b){a = b;}
  };
A const A_num(5);
// const A A_num(5); 和上面的那个常对象是等价的
/*
    注意:
    1. 在定义常对象的时候,必须要有初值
    2. 如果定义常对象,则不能调用该对象中非const成员函数(系统隐式调用的构造函数和
       析构函数)
    3. 增加数据的安全性,防止误操作而改变相关数据
    4. 常对象的成员数据都是常成员数据,因此常对象的构造函数只能用参数初始化表对常数
       据成员进行初始化。*/
  1. 常成员数据
    const 数据类型 常量名
class A
{
  private:
      const int num;
  // 常成员数据赋初值
  A(int num1){num = num1;} //错误
  A(int num1):num(num1){}  //正确
  /*常成员数据的作用和用法与普通常量变量相似,用关键字const来声明常数据成员。常数据
    成员的值是不能改变的。*/
};
  1. 常成员函数
    类名::fun(形参) const
class A
{
  private:
      int num_a;
      int num_b;
      int sum;
  public:
      A(int a = 5, int b = 6){num_a = a; num_b = b;sum = 0;}
      void sum_num() const;
}
A::void sum_num() const
{
    sum = sum_a + sum_b;
}
/*注意:
       1. const是函数类型的一部分,在声明函数和定义函数时都要有const关键字,
          在调用时不必加const;
       2. 常成员函数可以引用const数据成员,也可以引用非const的数据成员。
          const数据成员可以被const成员函数引用,也可以被非const的成员函数引用。
  */
  1. 常数组
    类型说明符 const 数组名[大小]
int const arr[10];
  1. 常指针
    const 类型说明符 指针名* 或者 类型说明符 const 指针名*
const int *p;
int const *p;
[ const使用场景 ]
  1. const修饰普通变量(例如:全局、局部变量);

  2. const修饰函数形参,一般和引用同时使用;

  3. const修饰函数返回值;

  4. const修饰类数据成员,必须在构造函数的初始化列表中初始化;

  5. const修饰类成员函数,实际修饰隐含的this,表示在类中不可以对类的任何成员进行修改;

  6. 在const修饰的成员函数中要对类的某个数据成员进行修改,该数据成员定义声明是必须加mutable关键字。

  7. const修饰this指针不能改变
    const对象可以调用非const成员函数和const成员函数吗?

    不能,调用非const成员函数(如果调用非const则与const相矛盾);
    可以,调用const成员函数。

非const对象可以调用非const成员函数和const成员函数吗?

    都可以调用。

const成员函数内可以调用其它的const成员函数和非const成员函数吗?

    不能,调用其它的非const成员函数;
    可以,调用其它的const成员函数。

非const成员函数内可以调用其它的const成员函数和非const成员函数吗?

    都可以调用。

2. static

static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。

static在C和C++中的区别:
C语言:
1。变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别;
2.变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
C++:
1、静态成员为所有类对象所共享,不属于某个具体的实例;
2、类静态成员即可用类名::静态成员或者对象.静态成员来访问;
3、类静态成员变量必须在类外定义,定义时不添加static关键字;
4、类的静态成员函数没有默认的this指针,因此在它里面不能使用任何非静态成员。
5、静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值,const修饰符等参数。
注意:
A.若全局变量仅在单个文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

C++静态成员函数问题:
1.静态成员函数可以调用非静态成员函数吗?
不能;静态成员函数没有this指针,是所有类对象公有的。成员函数有this指针,每个对象都有自己独立的一份。在调用成员函数时,实际上是this->成员函数。一个类的静态成员中去访问其非静态成员之所以会出错是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。
2.非静态成员函数可以调用类的静态成员函数吗?
可以;非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。

3. extern

在C语言,用extern修饰符修饰的变量或者函数,表示“此变量或者函数在其它文件已经定义,在这里只做引用处理”。

// file.cpp
int num = 100;
// file2.cpp
#include <iostream>
using namespace std;
extern int num;
int main()
{
    cout << "num = " << num << endl;
    return 0;
}

编译时,将file.cpp 和 file2.cpp一起编译,其运行如下:

g++ file.cpp file2.cpp -o file //编译
./file // 运行执行文件
num = 100

注意:
extern声明的位置对其作用域也有关系,如果是在main函数中进行声明的,则只能在main函数中调用,在其它函数中不能调用。

// file3.cpp
#include <iostream>
using namespace std;
int sum_num()
{
    int sum = 0, b = 2;
    sum = num + b;
}

编译时,其运行如下:

g++ file.cpp file2.cpp file3.cpp -o file //编译
// 出现错误提示,编译不过去
// 在file3.cpp中num为定义
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 题目类型 a.C++与C差异(1-18) 1.C和C++中struct有什么区别? C没有Protection行为...
    阿面a阅读 7,627评论 0 10
  • const 引用 const 引用是指向 const 对象的引用:const int ival = 1024;co...
    rogerwu1228阅读 617评论 0 1
  • 起床时间:5:40 运动项目:慢跑 成果:4 km,32分钟,280大卡
    温暖的小胖纸阅读 499评论 0 50
  • 第一代写字楼 普通型商务写字楼 (50年代至80年代初) 第一代写字楼一般是指计划经济体制下的行政办公...
    夕阳黄昏阅读 1,021评论 0 0
  • 我不知道该怎么形容当时的心情,当我把口袋里的零钱放到那个大概站起来只有我膝盖那么高的人的面前的盆里的时候,我的鼻子...
    AliceTD阅读 280评论 0 0