const与是static的区别

fuqianli 2009-04-21 03:06:32
const与是static的二者的区别
...全文
4700 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
morris88 2009-04-21
  • 打赏
  • 举报
回复 4
使用const。
这一点在很多经典的关于C 和C++的书籍中是必谈的要点。在《Exceptional C++》一书中,对这点有很精彩的描述,现摘录如下:“没有正确的安全意识的枪手在世界上是不可能活的很长的。const 观念不正确的程序员也是一样和没有时间戴紧帽子的正确,没有时间检查带电电线的电工一样不会活的很长。”在C 语言中,const 修饰符表示告诉编译器此函数将不会改变被修饰的变量的指向的任何值(除了强制类型转换)。当把指针作为参数传递时,总是合适地使用const,不仅可以防止你无意中错误的赋值,而且还可以防止在作为参数将指针传递给函数时可能会修改了本不想改变的指针所指向的对象的值。如:
const int num= 7;
num = 9; //有/可能得到编译器的警告。
const char *ptr,则表示该指针所指向的内容不会被改变,如果在程序中被发生对其赋值的操作,编译时将出错误提示。如:
const char *ptr = “hello”;
*ptr = 'H';//错误,所指内容不可改变也可将const 放在星号后面来声明指针本身不可改变。如:
char* const ptr;
ptr++; //错误,指针本身不可改变
也可同时禁止改变指针和它所引用的内容,其形式如下: const char* const ptr;
使用static
static 是一个能够减少命名冲突的有用工具。将只在一个模块文件中的变量和函数使用static 修饰,将不会和其他模块可能具有相同名称的函数和变量在模块连接时不会产生名称冲突。一般来说,只要不是提供给其它模块使用的函数,和非全局变量,均应使用static 修饰。将子程序中的变量使用static 修饰时,表示这个变量在程序开始时分配内存,在程序结束时释放,它们在程序执行期间保持它们的值。如:
void func1(void)
{
static int time = 0;
time++
}
void func2(void)
{
static int time = 0;
time++;
}
两个子程序中的time 变量使用static 修饰,所以它们是静态变量,每调用一次time将进行加1,并保持这个值。它们的功能与下面程序相似:
int time1 = 0;
int time2 = 0;
void func1(void)
{
time1++
}
void func2(void)
{
time2++;
}
我们可以看出,使用static 修饰后,模块中的全局变量减少,使得程序的更为简单。
lori227 2009-04-21
  • 打赏
  • 举报
回复
const 是常量~~
static 是静态变量
baiwei156 2009-04-21
  • 打赏
  • 举报
回复
一、const关键字

如果把const放在变量类型名前,说明这个变量的值是保持不变的,该变量必须在定义时初始化,初始化后对它进行的任何赋值都是非法的。

当指针或者引用指向一个常量时,必须在类型名前使用const标识这个指针或者引用指向的“变量”为常量,没有的话就是语法错误。如: const int x = 5; const int* px = &x; const int& rx = x;这样一来,直接修改x是不可能的,通过*px或者rx修改x也是不可能的。当然,这个指针还能指向其他的地方,因为指针本身并没有被标识为const的。比如,px = &y;

假如变量是一个非常量变量,而指针或者引用的类型名前使用了const,那么,可以直接修改变量,不能通过指针或者引用修改变量。

如果想让一个指针本身成为const的,就要在*后加const,即int* const p = &x;这个时候,p就不能再指向其他变量。假如x是非常量的,那它可以通过指针进行修改,因为x并没有标识为const。当然,引用天生就是const的,它必须被初始化,而且初始化后就不能再指向新的变量。比如,int x = 5; int& r = x; r = y;第二句代码不会让r指向y,而是让x的值变成了y。

如果在函数接口(参数)中使用const,和在值、指针中使用是类似的。但是,这就更难让函数返回指向这个参数对象的指针或者引用了。如果允许的话,客户代码就有可能通过别名修改常量。比如,

class Point

{

int x, y;

public:

Point closestPointVal(const Point& pt)

{ if( x*x+y*y < pt.x*pt.x+pt.y*pt.y)

return *this;

else return pt;}

Point* closestPointPtr(const Point& pt)

{ return (x*x+y*y < pt.x*pt.x+pt.y*pt.y) ? this : &pt;}

Point& closestPointRef(const Point& pt)

{ return (x*x+y*y < pt.x*pt.x+pt.y*pt.y) ? *this : pt;}

};

第一个函数是返回值的,不管用不用const,都不会修改实参pt。而第二个函数可以返回指向pt实参的指针。客户代码就可以使用这个指针修改实际参数对象的状态。同样,第三个函数返回的引用也能修改实参对象的状态。假如这样的函数是合法的,那么就有可能误用,误用后如果出了错,很难弄清是这里出的错,所以编译程序直接就认为这样的函数不合法。也就是,参数对象使用了const,而返回类型没有,这是错误的。

C++提供了三种方法解决这个问题:1.参数不使用const;2.在成员函数内部,使用const_cast运算符移去const属性;3.在另外合适的地方添加const。一个真正的程序员是不会放过任何一个机会,将设计人员的设计意图传达给客户代码程序员和维护人员的。所以,假如某个参数没有被修改,就要用const来明确说明。而使用const_cast也很糟糕,不易理解。所以只能使用第三种方法,在函数返回值前加上const,接收该返回值的指针或者引用也要是const的。这样的话,返回值只能作为右值,不能作为左值。这样的返回值不能调用它所在类的成员函数。

C++提供const关键字,不是为了保证一个变量不被修改,而是为了方便编译程序和维护人员弄清楚一个实体在程序中是否被修改了。如果函数接口中声明参数为const,我们就认为这个参数不会改变,如果没有声明为const,就认为这个参数一定被改变了,而不管函数到底有没有改变这个参数。

其实,const还有一个含义,就是在函数的参数列表的“)”之后,函数体的“{”之前。这种用法说明函数不会修改目标对象的值。

二、静态类成员

每建立一个类对象实例,都会为该实例创建一个单独的数据成员集合。不管是将对象定义为有名的局部变量,有名的全局变量,或者使用new定义为未命名的动态变量,或者按值传递一个对象作为函数参数,或者从一个函数按值返回一个对象。而对于成员函数,它们的目标代码却只产生一次。因为每个程序函数都有一个隐含的参数,即this指针。

1 用全局变量作为类特性

类为对象实例提供了一个蓝图或者说是模板,类的成员变量都是这个类的所有实例的共性,类的每一个实例都有一个单独的副本。但是有时我们需要为一个类的所有实例提供共有的数据成员副本,这比在每个类对象中维护单独的副本能更有效的合理利用内存。最常见的例子就是对类的实例进行计数。假如这个计数变量count被定义在类中,在构造函数中对其加1,在析构函数中对其减1,似乎能实现计数作用。但是实际上却是做不到的。因为count是类的成员变量,每个实例都有一个count,构造函数对其加1,只是对自己的count加了1。

使用全局变量就能解决这个问题。但是将它用在大型程序中,存在一些问题,这些问题在前面都讲过了。首先在客户代码任意地方都可能使用count,增加了模块之间的依赖性。其次,全局变量名增加了重名机会。最重要的是,count作为全局变量出现时,维护人员不能很好的了解它是做什么的,除非看注释或者查阅大量其他代码。

2 static的含义

static和const一样很复杂。

首先,将static用于一个全局变量,是说明该全局变量只对定义在同一个文件中的函数可见。即使在另一个文件中使用了extern,另一个文件中的函数也不能访问这个全局变量。

static的第二个含义是用于一个函数前,说明该函数只能在同一个文件中调用。

第三个含义是static用于函数的局部变量。它表明该变量的值不会因为函数终止而消失,它会被保存下来。再次调用该函数时,这个保存下来的值会用来初始化该变量。

第四个含义就是用于类的成员变量。它表明对类的所有对象,这个数据成员都只有一个实例。这个实例被所有对象共有。static的成员变量可以是private、public、protected的。定义和访问的语法也和其他数据成员一样。

3 静态数据成员的初始化

静态数据成员在类规格说明外部被初始化,这一点和全局变量相似。但是全局变量可以被隐式地初始化为0,而静态成员变量作为类的数据成员,必须被显式地初始化,因为类的所有的数据成员都必须被显式初始化。赋值和初始化存在着重要的区别,如果类型名后紧跟着变量名,就是初始化,如果变量名前没有类型名,就是赋值。初始化对于公共的和非公共的静态数据成员是合法的,但是对非公共的静态数据成员进行赋值却是不合法的。比如,如果count是private的,那么Point::count = 0就是错误的。

静态数据成员只能被初始化一次,所以它应该和其他的成员函数的定义一起放在.cpp文件中,而不能放在头文件中。一个静态数据成员不能是联合的成员,也不能是位域的类。联合和位域都表示属于某个特定对象的特殊内存用途,而静态数据成员却不属于特定对象,它属于整个类。

4 静态成员函数

static的第五种含义是用在类的成员函数前,表明这个函数不访问非静态数据成员,它只能访问它的参数、类的静态数据成员、全局变量。注意到静态成员函数访问的三种类型的数据,都不是描述对象状态的。而在函数参数列表后面使用const表明该函数不会修改该函数的目标对象的数据成员。所以,一个静态成员函数没有必要在参数列表之后添加一个const。

静态成员函数可以通过对象来调用,也可以直接使用类名来调用。因为它是类的特性,而不是对象的性质。

定义类的某个数据成员为静态变量,以表明此全局数据逻辑上属于该类。定义类的成员函数为静态函数,表明此全局函数逻辑上属于该类,而该函数只对静态数据、全局数据、参数进行操作。

liqianfu0214 2009-04-21
  • 打赏
  • 举报
回复 2
对于C/C++语言来讲,
const就是只读的意思,只在声明中使用;
static一般有2个作用,规定作用域和存储方式.对于局部变量,static规定其为静态存储方式,每次调用的初始值为上一次调用的值,调用结束后存储空间不释放;
对于全局变量,如果以文件划分作用域的话,此变量只在当前文件可见;对于static函数也是在当前模块内函数可见.
static const 应该就是上面两者的合集.
下面分别说明:
全局:
const,只读的全局变量,其值不可修改.
static,规定此全局变量只在当前模块(文件)中可见.
static const,既是只读的,又是只在当前模块中可见的.
文件:
文件指针可当作一个变量来看,与上面所说类似.
函数:
const,返回只读变量的函数.
static,规定此函数只在当前模块可见.
类:
const,一般不修饰类,(在VC6.0中试了一下,修饰类没啥作用)
static,C++中似乎没有静态类这个说法,一般还是拿类当特殊的变量来看.C#中有静态类的详细说明,且用法与普通类大不相同

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧