c/c++ const与static
前言
const 在C++里是常量 存在于符合常量表里。
static 在类里面使用 是属于类的,还没有对象就可以使用。
一、C语言与C++ 的const 区别
c:
#include<stdio.h>
int main()
{
const int num = 100;
printf("num = %d\n",num);
//num = 200; //编译通不过, 只读不可直接修改
int *p = # //编译通过,会有警告 , 可通过指针间接修改num值
*p = 200;
printf("num = %d\n",num);
return 0;
}
c++:
#include<iostream>
using namespace std;
int main()
{
const int num = 100;
cout<< "num = "<<num <<endl;
//num = 100; //编译通不过, 只读不可直接修改
//int *p = & num;// 无效类型转换 const int * --> int *
int *p = (int *)& num; // 强制类型转换后,*P可以修改,但输出的num等于原来的值,*P = 新值
// 因为 在定义 num时为 限定为const,编译器会把该num放到符号常量表里,
// 之后用到num时会从符号常量表读取值,*p指向的num为开辟存储空间时num的地址,所以有被修改
*p = 200;
cout<< "num = "<<num <<endl;
cout<< "*p= "<<*p <<endl;
cout<< "p= "<<p <<endl;
cout<< "&num= "<<&num <<endl;
return 0;
}
1、同一文件修饰一般变量的使用
①、c语言中对 const 的处理和普通变量一样,会到内存中读取数据
②、C++ 对 const 的处理更像是编译时期的#define,是一个值替换的过程,只存放在符号常量表里。
2、作用域区别:
C语言的const是外部链接(可通过extern引用),c++是内部链接
c:外部链接
const int num = 100; //默认外部链接,其他文件直接extern 进行使用
c++:内部链接
extern const int num = 100;//内部链接 如不加extern 其他文件是找不到的编译错误
// 只在定义的文件里使用。如外部需要使用要 在前面加extern
其他文件进行外部的引用:
int main()
{
extern const int num;
printf("num = %d\n",num);
}
二、C++ const在函数的使用(类外)
1.作为参数的const修饰符
void fun0(const A* a ); //保护了原指针所指向的内容
void fun1(const A& a); //不能对传递进来的引用对象进行改变,保护了原对象的属性
参数const通常用于参数为指针或引用的情况;
2.作为函数返回值的const修饰符
const A fun2( );
const A* fun3( );
三、const / static 在类的使用
原则:不可被修改 const内部不可修改,外部调用const没关系
#include<iostream>
using namespace std;
class A
{
public:
A(int a);
void Fun1() const;
void Fun2();
static void Fun3();
static int dd;
private:
int i = 1;
static int aa;//静态数据成员的声明,不属于某个对象,在类外初始化
const int bb;//常量数据成员 需要在初始化列表初始化
static const int cc;//常量静态数据成员(可以在构造函数中初始化)
};
int A::aa = 10; //静态成员的定义+初始化
const int A::cc = 30; //静态常量成员定义+初始化
int A::dd = 99;
A::A(int a):bb(a) //常量成员的初始化
{
aa+=1;
}
void A::Fun1() const
{
cout << " const fun1"<<endl;
//i++; //不可修改非const成员
aa++; //可修改static变量 一位static 不属于对象属于类
cout << i <<endl;
cout << aa <<endl;
cout << bb <<endl;
cout << cc <<endl;
}
void A::Fun2()
{
cout << "no const fun2"<<endl;
//bb++; bb为const常量
cout << aa <<endl;
cout << bb <<endl;
cout << cc <<endl;
}
void A::Fun3()
{
cout <<"A::dd :"<< A::dd<<endl; //只可调用static成员数据,不可调用非static
}
int main()
{
/*******CONST**********/
A tmp(20);
tmp.Fun1();//调用const 成员函数
tmp.Fun2();
const A tmp2(30);
tmp2.Fun1();//const对象 只能调用const 成员函数
//tmp2.Fun2(); //不可调用非const函数
/*******STATIC**********/
A::Fun3(); //static Fun3属于类 不创建对象可直接调用
A::dd++; //static dd属于类 不创建对象可直接调用
cout << "A::dd "<<A::dd<<endl ;
return 0;
}
1、const 修饰类对象
const A tmp;
调用对象的函数只能是 const成员函数
2、const 修饰类成员变量
const int bb;//常量数据成员 需要在初始化列表初始化
A::A(int a):bb(a) //列表初始化常量成员bb
{
aa+=1;
}
3、const 修饰类成员函数
void Fun1() const; //声明函数 ,不仅可被const对象调用,也可被非const调用
//不可对非const变量进行修改
void A::Fun1() const
{
cout << " const fun1"<<endl;
//i++; //不可修改非const成员
aa++; //可修改static变量 一位static 不属于对象属于类
cout << i <<endl;
cout << aa <<endl;
cout << bb <<endl;
cout << cc <<endl;
}
4、const函数 里可修改与访问mutable
用于定义更改频繁的数据成员. 数据成员即使在const对象或在const成员函数中都可以被修改
class CRect{
public:
int getwid() const;
private:
mutable int m_wid;
};
int CRect::getwid(){
return m_wid*1.1;
}
5、static 修饰类成员变量
需要在类外初始化,static属于类,不属于对象,在类定义好后就创建好了
static int dd; //需要在类外初始化
int A::dd = 99;
6、static 修饰类成员函数
只可以调用静态的成员变量或函数,没有this指针。其继承类派生类都可以调用。
static void Fun3();
void A::Fun3()
{
cout <<"A::dd :"<< A::dd<<endl;//只可调用static成员数据,不可调用非static
}
7、static 与 const 修饰成员变量
本质上是static变量 其值是const常量不可被修改
可被const成员函数和static成员函数访问。
const和 static不可在成员函数共用,即没有static fun() const;
static const int cc;
const int A::cc = 30;