浅谈C++中的几个关键字 : static, const, inline
来源:互联网 发布:淘宝直通车最低充值 编辑:程序博客网 时间:2024/06/05 15:38
浅谈C++中的几个关键字 : static, const, inline
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static
static是C++中很常用的存储类说明符,它被用来控制变量、函数的存储方式同链接方式。
下面我将从static 存储类说明符的产生原因、作用谈起,全面分析static 说明符的实质。
static 说明符的两大作用:
一、控制存储方式
static 说明符被引入,以告知编译器将变量存储在程序的静态存储区,而非栈上空间。
1、引出原因:
函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,而当程序执行到其作用域外时会释放掉。
这就产生了一个问题:如果想将函数中此变量的值保存至下一次调用,该如何实现?
最容易想到的方法是定义一个全局变量,但定义一个全局变量有着许多缺点,最明显的就是扩大了此变量的作用域,使得此变量
可经由其他函数或语句改写。
2、解决方案:
因此在C++ 中引入了static 说明符,用它来修饰变量,它能够指示编译器为此变量在程序的静态存储区分配空间保存,这样既实现
了目的,也没有没有改变其原有的作用域。
二、控制链接方式
对于所有不在函数内或语句块内声明的对象,默认有外部链接。即在多个文件中可声明多次,但只指向同一个对象
如果在声明对象时引入 static, 则所声明的变量或函数只在当前文件内可见,使得外部链接变为内部链接。
static作用分析总结:
static 说明符总是使得变量或对象的存储形式变成静态存储,对于全局变量是内部链接,对于局部变量是无链接。
对于局部变量,改变了其存储方式;对于全局变量,改变了其链接方式。
类中的static 成员:
一、出现原因及作用:
1、需要一个数据成员由类的各个对象共享,为整个类而非某个对象服务。
2、力求不破坏类的封装性,要求此成员隐藏在类的内部,对外不可见。
类的static 成员满足了上述要求,因为它具有如下特征:有独立的存储区,属于整个类。
二、注意:
1、对于静态数据成员,链接器会保证它拥有一个单一的外部定义。静态数据成员按定义出现的先后顺序依次初始化,
注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。
2、类的静态成员函数是属于整个类而非类的对象,所以它没有this 指针,这就导致了它公能访问类的静态数据和静态成员函数。
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const
const 是C++ 中常用的类型限定符,但我在工作中却发现,许多人使用它仅仅是想当然,这样有时也会用对,但在某些微妙的场合,可就没有那么幸运了。
究其实质原由,大多因为没有搞清const 类型限定符的本质。这里我将对const 类型限定符进行一个分析,溯其本源究其本质,希望对大家理解const 有所帮助。
C++中为什么要引入 const
C++ 的作者当初是出于怎样的目的引入(或称保留) const 关键字的呢? 这是一个有趣又有益的话题,对理解 const 很有帮助。
1。大家知道,C++ 有一个类型严格的编译系统,这使得C++ 程序的错误在编译阶段即可发现许多,从而使出错率大为减少,
也因此 成为了C++ 与 C 相比有些突出优点的一个方面。
2。C 中很常见的预处理指令 #define VariableName VariableValue 可以很方便地进行值替换,这种替换在至少在以下三个方面
优点表现突出:
- 一是避免了意义模糊的数字出现,使得程序语义清晰流畅, 如下例: #define USER_NUM_MAX 108 。这样就避免了直接使用数字108带来的困惑。
- 二是可以很方便地进行参数的调整与修改。如上例,当人数由108变为200时,在此改动一处就可。
- 三是提高了程序的执行效率。由于使用了预编译器进行值替换,并不需要为这些常量分配存储空间,所以执行效率较高。
鉴于以上的优点,这种预定义指令的使用在程序中随处可见。
3。说到这里,大家可能会迷惑上述所讲的1、2两点同 const 说明符有什么关系。好,请接着下看:
预处理语句虽然有些以上所述的许多优点,但它也有个比较致命的缺点。即,预处理语句仅仅只是简单的值替换,缺少类型的检测机制。
这样的预处理语句就可能享受 C++ 严格类型检查的好处,从而可能成为引发一系列错误的隐患。
4。好了,第一阶段结论好了:
结论: const 说明符推出的初始目的,就是为了取代预编译指令 #define ,在继承其优点的同时消除它的缺点。
现在的它形式变成了:
const Tpye VariableName = VariableValue;
为什么 const 可以很好地取代预定义语句呢? 请看
1、首先,以const 说明符修饰的常量值具有不可变性。这是它可取代预定义语句的基础。
2、第二,它也同样可以避免意义模糊的数字出现,使得程序语义清晰的同时可以很方便地对参数进行调整与修改。
3、第三,C++ 编译器一般不为普通 const 常量分配存储空间,而是将们保存在符号表中,这使得它真正成为了一个编译期间常量。
由于 没有了存储与读内存的操作,这使得它的效率也很高。这是它取代预定义语句的重要基础。
4、最后,const 定义也同一般普通的变量定义一样,它会由编译器对它进行类型的检测。消除了预定义语句的隐患。
const 说明符使用情况分类详析
1。const 说明符用于指针的两种情况分析:
int a ;
const int *p ; // 指针类型为 const int *, 指针指向类型为 const int 。指针变量为非 const 类型,但指向的的变量为 const 类型
int *const p = &a ; // 指针类型为int *const , 指针指向 int 。指针变量为 const 类型,指向的变量为 非const 类型
const 类型指针的转换问题:
1.、从" const 指针类型 " 到 " 非const 指针类型 " 的转换:
除了 const char * 指针类型 可转换为 char * 类型外(这是为了对c语言的向下兼容) ,
任何的 const type1 * 都不可转换为 type2 * 类型。
2、从 " 非const 指针类型 " 到 " const 指针类型 " 的转换:
这样的转换都是可以执行的。
2。const 说明符限定函数的传递值参数:
void Fun( const int Var);
分析:
上述写法限定了参数Var不可在函数体内改变。而由值传递的特点可知,就算Var在函数体中改变了也不会影响到函数外部。
所以,此限定与函数的使用者无关,仅与函数的编写者有关。
结论:最好在函数的内部进行限定,对外部调用者屏蔽以免引起困惑。如可改写如下:
void Fun( int Var)
{
const int &VarAlias = Var;
.....
}
3。const 限定函数的返回值类型
const int Fun1();
const MyClass Fun2();
const int &Fun3();
cosnt int *Fun4();
const MyClass &Fun5();
const MyClass *Fun6();
分析:
上述写法仅限定函数的返回值不可被改写。
1.当函数返回为内置类型的数据时,那已经是一个数值,那是必定不可改写的,这时的const 可要可不要。但建议去掉。
2.当函数返回为自定义类型的对象,这时的对象仍然可能包含可被赋值的数据成员,所以此时有意义。
3.如返回的是一个引用或是指针时,这种情况最为常见,由地址变量的特点可知,适当使用const ,意义昭然。
4。const 限定类的成员函数
class ClassName
{
public:
int Fun() const;
.....
}
注意:
采用这种const 后置的形式是一种规定,也是为了不引起混淆。在这个函数的声明和定义中均要使用const,因为const已经成为类型信息的一部分。
获得能力:可以操作常量对象。
失去能力:不能修改类的数据成员,不能在函数中调用其他不是const的函数。
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
inline
在上面谈了const后,下面再来谈一下inline这个关键字。之所以把inline放在这个位置,是因为inline这个关键字的引入原因和const十分相似。
下面分为如下几个部分进行阐述。
C++中引入inline关键字的原因:
inline 关键字用来定义一个类的内联函数,引入它是为了取代C语言中表达式形式的宏定义。
表达式形式的宏定义一例: #define ExpressionName(Var1,Var2) (Var1 + Var2) * (Var1 - Var2)
一、为什么要取代这种形式呢,且听老夫慢慢道来:
1.首先我们谈一下在C中使用这种形式宏定义的原因。
C语言是一门效率很高的语言,这种宏定义在形式和使用上就像一个函数,但它使用预处理器来实现,没有了参数压栈、代码生成等一系列的操作。
这样一来它的效率很高,这是它在C中被使用的一个主要原因。
2.这种宏定义在形式上类似于一个函数,但在使用它时,仅仅只是做预处理器符号表中的简单替换,因此它不能进行参数有效性的检测,也就不能享受C++编译器严格类型检查的好处。
另外它的返回值也不能被强制转换为可转换的合适的类型。这样,它的使用就存在着一系列的隐患和局限性。
3.在C++ 中引入了类及类的访问控制,这样,如果一个操作或者说一个表达式涉及到类的保护成员或私有成员,
你就不可能使用这种宏定义来实现(因为无法将this指针放在合适的位置)。
4. inline 推出的目的,也正是为了取代这种表达式形式的宏定义。inline 很好地继承了它的优点同时也消除了化的缺点。
二、为什么inline能很好地取代表达式形式的预定义呢?
对应于上面的1-3点,阐述如下:
1. inline 定义的类的内联函数,函数的代码被保存在符号表中,在使用时直接进行替换(像宏一样展开),没有了调用的开销,效率很高。
2.很明显,类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。
然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。
3. inline 可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。
三、在何时使用inline函数:
1.首先,你可以使用inline函数完全取代表达式形式的宏定义。
2.另外要注意,内联函数一般只会用在函数内容非常简单的时候。这是因为,内联函数的代码会在任何调用它的地方展开,
如果函数太复杂,代码膨胀带来的恶果很可能会大于效率的提高带来的益处。内联函数最重要的使用地方是用于类的存取函数。
四、如何使用类的inline函数:
简单提一下inline 的使用吧:
1.在类中定义内联函数:
隐含式定义内联函数
class ClassName
{
....
// 如果在类中直接定义,可以不使用inline修饰。默认为内联
int GetWidth() {return m_lPicWidth;}; ....
....
}
2.在类中声明,在类外定义:
class ClassName
{
....
// 如果在类中直接定义,可以不使用inline修饰
int GetWidth();
....
}
inline int GetWidth()
{
return m_lPicWidth;
}
- 浅谈C++中的几个关键字 : static, const, inline
- C++中的几个关键字:static,const,inline
- C/C 关键字static,const,inline,define,typedef
- static、const、define、inline关键字
- C/C++关键字static,const,inline,define,typedef
- [转]C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- 【zz】C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- c/c++关键字static,const,inline,define,typedef
- C/C++关键字static,const,inline,define,typedef
- C语言关键字:static,const,inline,volatile与assert()等
- C++中的几个关键字(static、const、#define、inline、sizeof与strlen、指针与引用、new与malloc)
- C语言中几个关键字(inline,volatile,static)
- sadsad
- 用DataList来做一个仿当当网上书店的小应用
- Android放大镜的实现
- yum history 历史记录功能
- hdu 2047
- 浅谈C++中的几个关键字 : static, const, inline
- 网络摄像头4 cmos 0v9650,driver
- masm汇编,接上一篇 在屏幕中央画一个逐渐膨胀的实心圆
- 第十五天(类继承 · 二)
- Web项目开发的一般流程
- FCK功能简化
- Jetty和Tomcat的选择:按场景而定
- 在源eclipse上,以安装插件方式,安装myeclipse .
- Java From The Beginning 02_Eclipse