C++ 中 static 与 const 的用法及对比
在这个学习过程中我对 static 及 const 的使用时常会混淆,因此整理,加深记忆
一、类的静态成员
如果某个属性为整个类所共有,不属于任何一个具体对象,则采用 static 关键字来声明静态成员。
• 由于静态数据成员不属于任何一个对象,因此可以通过类名对它进行访问。
使用方法----- "类名::标识符“ (注意:static 数据成员的初始化要在类定义之外在加以定义)
1.静态数据成员
#include<iostream>
using namespace std; class Dog {
public:
Dog(int age, int weight);
void show();
~Dog() {}
private:
static int number;
int age, weight;
};
int Dog::number = ; //static 数据的定义【因为需要这种方式专门为它们分配空间,而非静态数据是与它们的所属对象一同分配空间的】 Dog::Dog(int age, int weight) { //构造函数
this->age = age;
this->weight = weight;
number++;
} void Dog::show() {
cout << "age: " << age << "岁 " << "weight: " << weight <<"kg"<< endl;
cout << "现在共有" << number << "只汪星人" << endl;
} int main() {
Dog dog(, );
dog.show(); Dog dog2(, );
dog2.show();
return ;
}
结果如下:

不难发现当调用构造函数时 计算汪星人的数量的 number静态数据 做自增运算时,无论在哪个对象里number的值随上一次调用而继续加一。
有个细节:static 数据类型 在定义时不给它设定值的化,系统默认为 0,而非静态数据类型则随机赋值。(ps:下面代码 14 行也值得注意)
#include<iostream>
using namespace std; class Point {
public:
Point() {};
void set(int x, int y);
int getx() { return x; }
int gety() { return y; }
private:
int x;
static int y;
};
int Point::y; //切记,哪怕不给static类型 定义时赋初值,也需要在类外面定义【即分配空间】,否则会报错
void Point::set(int x, int y) {
this->x = x;
this->y = y;
}
int main() {
Point p;
cout << p.getx() << " " << p.gety() << endl;
return ;
}
结果如下:

2.静态成员函数
静态成员函数可以直接访问该类的数据和函数成员,而访问非静态成员必须通过对象名
class A {
public:
    static void f(A a);
private:
    int x;
    static int y;
};
static int y;
void A::f(A a) {
    cout << x;          //错误
    cout << a.x;        //正确
    cout << y;      //直接访问static 数据正确
}
从上面几个例子中,我们发现静态成员函数可以直接访问静态数据类型而访问非静态数据类型时需要通过对象名来实现。
而非静态函数则可以直接访问这两种数据类型
静态函数的访问【例子】(注意22行):
 #include <iostream>
 using namespace std;
 class Cat {
 public:
     Cat() { numOfCats++; }
     static void getNumOfCats();
 private:
     static int numOfCats;
 };
 int Cat::numOfCats = ;
 void Cat::getNumOfCats() {
     cout << "猫的数量:" << numOfCats << endl;
 }
 int main() {
     Cat::getNumOfCats();    //static函数属于类,并不属于某个对象,所以可以这样调用,当然通过对象也可以调用
     Cat cat;
     cat.getNumOfCats();
     Cat cat2;
     cat.getNumOfCats();
 }
二. 常对象
常对象是这样的对象:它的数据成员值在对下岗的整个生存周期内不能被改变,也就是说,常对象必须进行初始化而且不能被更新!
语法形式: const 类型说明符 对象名;
int main() {
    const int n = ;     //正确,用10对常对象初始化
    n = ;                //错误,常对象不能被赋值
}
用const 修饰的类成员
1. 常成员函数
类型说明符 函数命(参数表) const ;
注意:
(1)const 是函数类型的组成成分,因此在函数定义部分也要带const
(2)一个对象是常对象 ,则只能通过该常对象调用它的 常成员函数
(3)const关键字可以用于重载
#include<iostream>
using namespace std; class R {
public:
R(int r1, int r2) :r1(r1), r2(r2) {}
void print();
void print() const; //函数重载
private:
int r1, r2;
}; void R::print() {
cout << r1 << " " << r2 << endl;
} void R::print()const { //定义时const 依旧是要带的
cout << r1 << " " << r2 << endl;
} int main() {
R a(, );
a.print(); //调用13行print函数
const R b(, );
b.print(); //调用17行print函数
return ;
}
结果如下:

在逐步调试的过程中发现 常对象 b 在调用print函数时,调用了常成员函数,而非const对象a调用了 非常成员函数
因为通过非const对象调用print函数,两个重载函数都可以匹配,编译器将选择最近的函数重载----不带const的函数
ps:如果该程序中只有带const的print函数 则 普通对象a也是调用有const的print函数
But ,常对象b不能调用 普通print函数,因为普通print函数有着改值的可能,但常对象b不能改变值
2.常数据成员
将上面的代码类的声明改为
class R {
public:
    R(int r1, int r2) :r1(r1), r2(r2) {}
    void print();
    void print() const;
private:
    const int r1, r2;        //改为常数据
};
则类的初始化必须用
类名::类名(形参表):常数据1(形参1),常数据2(形参2)....{ }
因为常数据不能赋值!
还有一点,类的静态常量如果具有整数类型或枚举类型,那么直接可以在类定义中给它指定常量
class Dog {
public:
    Dog() {}
private:
    static const int a = ;
};
//=========上下二者等价=================
class Dog {
public:
    Dog(){}
private:
    static const int a;
};
int Dog::a = ;
总结:
对比static 以及 const 的用法
1. static 类型数据可以通过 static类型或者 非static类型函数访问并可以改变;
const类型数据不能改变;
2. static 函数可以直接访问 类中 static 类型数据,但访问非static数据需通过对象访问;
const类型函数可以被调用于非const对象,但在对象是const类型时,通过该对象只能调用const类型函数
=============================================================================================
以上为现阶段的学习记录,如有错误希望指正 :)
C++ 中 static 与 const 的用法及对比的更多相关文章
- C++中static、const使用方法简介
		
众所周知,在c++中,static和const的使用方法是难点,也是重点,值得我们随时温习,所谓温故而知新是也. 下面我们首先说一说static. 1.static的作用 static变量的作用,主要 ...
 - C++ ——  类中static和const关键字声明变量的初始化方式总结
		
在类中声明变量/常量时,经常会用到static.const关键字.对于该变/常量的初始化问题,网上有许多相关文章,但是大多不够完善,或者存在错误.经过实际验证,总结如下: (注明:测试编译平台为VS2 ...
 - PHP5中Static和Const关键字
		
(1) static static要害字在类中是,描述一个成员是静态的,static能够限制外部的访问,因为static后的成员是属于类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享, ...
 - C++中static和const关键字的作用
		
static关键字至少有下列几个作用: 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值: 在模块内的static全局变量 ...
 - C#中static静态变量的用法
		
使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员static修饰符可用于类.字段.方法.属性.运算符.事件和构造函数,但不能用于索引器.析构函数或类以外的类型 静态全局变量 定义 ...
 - C++中static与const成员
		
一.static成员 (1)static数据成员 static数据成员的创建是为了对象之间的共享和沟通,具有以下特点: 1.1 static数据成员属于类,只占一份空间(不像普通数据成员每个对象中都有 ...
 - Java中static变量作用和用法详解
		
static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...
 - 《OOC》笔记(1)——C语言const、static和extern的用法
		
<OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...
 - C/C++中const的用法                                                    分类:            C/C++             2015-07-05 00:43    85人阅读    评论(0)    收藏
		
const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结 ...
 
随机推荐
- UML图中时序图的基本用法
			
快速阅读 序列图主要用来更直观的表现各个对象交互的时间顺序,将体现的重点放在 以时间为参照,各个对象发送.接收消息,处理消息,返回消息的 时间流程顺序,也称为时序图. 里面用到的基本元素如下: 角色- ...
 - distribution system index
			
Resiliency:可译为容错性,强调从错误状态恢复的能力.形容词Resilient可译作“可容错的”. Elasticity:可译为伸缩性,强调根据负载进行水平伸缩的能力.形容词Elastic可译 ...
 - Emmet语法规则
			
HTML速写之Emmet语法规则 Emmet-写HTML/CSS快到飞起 在前端开发的过程中,最费时间的工作就是写 HTML.CSS 代码.一堆的标签.属性.括号等,头疼.这里推荐一个Emmet语法规 ...
 - T-MAX组--项目冲刺(第二天)
			
THE SECOND DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项目冲刺(第二天) 团队名称 T-M ...
 - C格式字符串转为二叉树
			
最近在LeetCode做题,二叉树出现错误时不好排查,于是自己写了一个函数,将前序遍历格式字串转换成二叉树. 形如 "AB#D##C##" 的字符串,"#"表示 ...
 - 随机森林算法OOB_SCORE最佳特征选择
			
RandomForest算法(有监督学习),可以根据输入数据,选择最佳特征组合,减少特征冗余:原理:由于随机决策树生成过程采用的Boostrap,所以在一棵树的生成过程并不会使用所有的样本,未使用的样 ...
 - HSCR | Hirschsprung‘s disease | 巨结肠 | 研究进展
			
这个网站介绍得很详细:Hirschsprung Disease,基本的定义.病因.诊断. Hirschsprung disease — integrating basic science and cl ...
 - c语言程序课程设计题目
			
<C语言程序设计>课程设计课题表 一.A类 .职工信息管理系统设计 职工信息包括职工号.姓名.性别.年龄.学历.工资.住址.电话等(职工号不重复).试设计一职工信息管理系统,使之能提供以下 ...
 - SQL中join和cross join的区别
			
SQL中的连接可以分为内连接,外连接,以及交叉连接 . 1. 交叉连接CROSS JOIN 如果不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积: 举例, ...
 - oracle/mysql经典电子书籍pdf下载
			
Oracle LZ写的书,深入结合oracle设计.优化/SQL优化.应用层架构与优化.大量生产案例,敬请期待... Oracle编程艺术 深入理解数据库体系结构(第3版) 链接:https://pa ...