(转 )C++ static、const和static const 以及它们的初始化
const定义的常量在函数执行之后其空间会被释放,而static定义的静态常量在函数执行后不会被释放其空间。但不论是Const还是static 他们定义的内容都会随着程序的结束而被系统清楚。
static 表示的是静态的。类的静态成员函数,成员变量是和类相关的,不是和类的具体对象相关,即使没有具体的对象,也能调用类的静态成员函数,成员变量。一般的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。
在c++中,const常量成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。
const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。
所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。
const数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。
如:
class Test
{
public:
Test(): a(){}
enum {size1=, size2 = }; private:
const int a; // 只能在构造函数初始化列表中初始化,这个似乎很少用到??? static int b;//这个变量与类 Test有关 而与之类的实例化对象没啥关系。。 const static int c; // 与static const int c;相同,可以在这里定义(如果以后在类中需要使用该变量的话). }
int Test::b = 0; // 不能以成员列表初始化,不能在定义处促使化,因为不属于某个对象。
const int Test:: c = 0;//注意:给静态成员变量赋值时,不在需要加static修饰。但const要加。
const 成员函数,主要的目的是防止修改对象的内容。即:int Fun() const; 不可以修改对象的数据,可以访问对象的数据,访问成员函数时,只能是const的,不能是non_const的成员函数。
static成员函数,主要的目的是作为类作用域的全局函数。不能访问类的非静态数据成员。类的静态成员函数的没有this指针,这导致:
1. 不能直接存取类的非静态成员变量,调用非静态成员函数
2. 不能被声明为virtual
下面是关于static,const,static const , const static成员的初始化问题。
1.类里的const成员初始化:
在一个类里建立一个const时,不能给它初值。像
class foo
{
private:
const int i = 100; // error !!! 必须要做类foo的构造函数里面初始化
public:
foo(){}
......
};
这样的初始化方式是不能通过编译的,因为在类对象里进行了存储空间分配,编译器不能知道const的内容是什么,所以不能把它用作编译期间的常量。这意味着对于类里的常数表达式来说,const就像它在C中一样没有作用。因此这个初始化工作必须发生在构造函数里,并且,要在构造函数的某个特别的地方。因为const必须在建立它的地方被初始化,所以在构造函数的主体里,const必须已初始化了,否则,就只有等待,直到在构造函数主体以后的某个地方给它初始化,这意味着过一会儿才给const初始化。当然,无法防止在在构造函数主体的不同地方改变const的值。
构造函数初始化表达式
class foo
{
private:
const int i = 100;
public:
foo(){......}
......
};
如果构造函数是在类外定义,则可以这样写:
class foo
{
private:
const int i;
public:
foo();
......
};
foo ::foo() : i (100) {......} // 初始化列表
2.类里的static成员初始化:
类中的static变量是属于类的,不属于某个对象,它在整个程序的运行过程中只有一个副本,因此不能在定义对象时对变量初始化,就是不能用构造函数来初始化。其正确的初始化方式是:
<数据类型><类名> ::<静态数据成员名> = <值> ,例如
class foo
{
private:
static int i;
public:
foo();
......
};
int foo ::i = 100;
这表明:
(1)初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。
(2)初始化时不加该成员的访问权限控制符private,public等。
(3)初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
3.类里的static const 和const static成员初始化:
在找static成员的初始化学习资料时,我发现了网上有很多关于 static const 成员,也就是全局的静态常量的初始化的资料。const成员要在构造函数初始化,而static成员在需要在在类体外初始化,那么static const和 const static 的成员应该在哪里进行初始化呢?这两个写法又会有什么不一样吗?其实他俩都一样。在借阅《Thinking in c++》中文版188页和做了相关实验后,我认为若在类内使用的话,static const 则必须在static const 定义之处进行初始化。其他情况在类里外都行。
比如:
class Test{
public:
static const int MASK1;
const static int MASK2;
};
const int Test ::MASK1 = 0xFFFF;
const int Test ::MASK2 = 0xFFFF;
它们没有区别,虽然
一个是静态常量,
一个是常量静态,
静态都将存储在全局变量区域,其实最后结果都是一样的。
可能在不同编译器内,不同处理,但是最后结果是一样的。
下面是一个完整的例子:
#ifndef A_H_
#define A_H_
#include<iostream>
using namespace std; class A{
private:
static int aa; //静态数据成员声明
static const int count; //静态常数据成员声明(可以在此初始化)
const int bb; //常数据成员
public:
A(int a);
static void print(); //静态成员函数
}; A::A(int a):bb(a) { //常成员的初始化
aa += ;
} void A::print() {
cout << "connt=" << count<< endl;
cout << "aa=" << aa << endl;
}; int A::aa = ; //静态成员定义
const int A::count = ; //静态常成员初始化
#endif int main(){
A a();
A::print(); //通过类访问静态成员函数
a.print(); //通过对象访问静态成员
}
但是注意:将static const datamember的申明放在头文件中时,新的C++标准支持,但VC6.0却不支持
(转 )C++ static、const和static const 以及它们的初始化的更多相关文章
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- const、static和extern的正确使用方式
我们在看一些大牛的第三方时,里面会出现很多const.static和extern,尤其是const和static,const和extern的结合使用,直接令很多小伙伴懵逼了,今天就详细讲解一下这三个关 ...
- 《OOC》笔记(1)——C语言const、static和extern的用法
<OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...
- static、const和static const
http://blog.csdn.net/rainkin1993/article/details/8068558 #include<iostream> using namespace st ...
- const、static、extern三个关键字
默认情况下,C语言的全局变量是全世界都可以访问的,也就是全局变量可以跨文件访问. extern可以引用全局变量 例如,如果有一个全局变量int money = 100;extern int money ...
- 到底是 const 还是 static readonly
真的一样? const 和 static readonly 常在程序中用来声明常量,调用方法也没有什么不同,他们真的一样吗?我们可以做个试验. 程序集内的常量 现在我们建立一个程序,里面有一个MyCl ...
- C: const and static keywords
原文:http://www.noxeos.com/2011/07/29/c-const-static-keywords/ C: const and static keywords Ok, once a ...
- 【转】const和static readonly
我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等.在多数情况下可以混用.二者本质的区别在于,const的值是在编译期间确定的,因此只能在声 ...
- (C#) What is the difference between "const" and "static readonly" ?
const int a must be initialized initialization must be at compile time readonly int a can use defaul ...
- php中$this、static、final、const、self 等几个关键字的用法
<?phpclass A { public static function get_self(){ return new self(); } public static function get ...
随机推荐
- Mongodb的性能优化问题
摘要 数据库性能对软件整体性能有着至关重要的影响,对于Mongodb数据库常用的性能优化方法主要有: 范式化与反范式化: 填充因子的使用: 索引的使用: 一. 范式化与反范式化 范式是为了消除重复数据 ...
- Socket的三个关联函数
/*lrs_save_param将静态或接收到的缓冲区保存到参数中*/lrs_save_param (char *s_desc, char *buf_desc, char *param_name, i ...
- Jhipster token签名异常——c.f.o.cac.security.jwt.TokenProvider : Invalid JWT signature.
背景,jHipster自动生成的springBoot和angularJs前后台端分离的项目.java后台为了取到当前登录者的信息,所以后台开放了 MicroserviceSecurityConfigu ...
- 你真的搞懂ES6模块的导入导出规则了吗
前言 模块作为ES6规范的核心部分之一,在实际项目开发中经常会看到它的身影,那么我们是否真正了解它的相关规则呢,今天就带大家一起了解一下模块的导入导出规则 导入 ES6模块的导入(即import)大致 ...
- solr初认识
Solr : Search On Lucene Replication Solr 基本概况 Apache Solr (读音: SOLer) 是一个开源的搜索服务器.Solr 使用 Java 语言开发, ...
- windows系统添加服务命令
管理员身份进入cmd sc create TestSvr binPath= D:\Program Files\test.exe start= auto
- Foundation框架中的NSNumber对象详解
到目前为止,我们所讨论过的所有数字数据类型,如int型.float型和long型都是Objective-C语言中的基本数据类型,也就是说,它们都不是对象.例如,不能向它们发送消息.然而,有时需要作为对 ...
- Java之自动拆装箱
顾名思义,自动拆装箱就是将基本类型和包装类进行自动的互相转换. JDK5.0后,将自动装箱/拆箱引Java中. 自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中 ...
- phpcms 列表页中调用其下的所有子栏目(或特定的子栏目)的方法
phpcms 列表页中,如何调用其下的所有子栏目(或特定的子栏目),具体的写法如下,感兴趣的朋友可以参考下,希望对大家有所帮助 代码如下: {pc:get sql="select * fro ...
- 【黑金原创教程】【TimeQuest】【第二章】TimeQuest模型角色,网表概念,时序报告
声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...