Posts Tagged ‘const’

August 17, 2010

  const在C,尤其是C++,是个老生常谈的问题,但这里不谈const具体有哪些特性,如何使用,而是说说const在C和C++中的区别。编译器,C使用gcc,C++使用g++,其它编译器(cl等)请自行验证。
  在我的印象中,const就是常量constant)。但这并不是真的。在C中,const仅仅表示其所修饰对象不可修改。常量和所谓“不可修改”有什么区别呢?C中,const int N = 10; 这样的语句声明了一个整型数据,声明之后你不能再为其赋值,此即为不可修改。但在C中,N却不是常量,而诸如372, 3.72, ‘A’之类才是常量,在C中定义常量通常使用#define。而在C++中,const int N = 10; 就会定义N为常量。
  怎么证明呢?你可能知道,定义静态数组,必须使用整型常量指定其大小,那咱们就用这个特性来验证上面描述的观点。

1
2
3
4
5
6
7
int
main(int argc, char **argv)
{
    const int N = 10;
    int a[N] = { 1, 2, 3 };
    return 0;
}
Tags: . 311 views
August 10, 2010

volatile

  可能很多人都没用过C/C++中的这个关键词,甚至不知道它的存在,本人以前也只是有所耳闻,但似懂非懂。
  这是一个类型修饰符,位置同conststatic等。一个使用volatile修饰的变量,比如volatile int i; 每次对该变量的直接引用,都会访问内存,而不是从寄存器中读取(如果其已经在寄存器中)。这样一来,volatile似乎没什么用处,反倒会使数据的读取相对变慢很多。但是,如果没有volatile,编译器可能会优化你的程序,使得数据从寄存器中读取,从而加快程序的运行,但如果这个变量是同其它进程/线程共享的,就可能造成数据的不一致。多线程情况下,你可以使用互斥机制来保证对共享数据访问的原子性。但是,在单片机等嵌入式环境中,硬件经常不会有这种互斥机制的支持,这时某些共享的数据(比如端口)就可能会产生不一致的情况。而使用volatile就会使编译器不对代码进行优化,每次对该变量的访问都会从内存中读取。
  下面通过观察使用volatile前后编译产生的汇编代码的不同,来加深对volatile关键词的理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ ... ]
main:
[ ... ]
	call	foo # 调用函数foo,返回值保存至寄存器eax
	movl	%eax, 44(%esp) # 为i赋值
	movl	44(%esp), %edx # 读取i值
	movl	44(%esp), %ecx # 读取i值
	movl	44(%esp), %eax # 读取i值
	movl	%ecx, 16(%esp) # 参数k入栈,使用i值
	movl	%edx, 12(%esp) # 参数j入栈,使用i值
	movl	%eax, 8(%esp) # 参数i入栈
	movl	$.LC0, 4(%esp) # 格式字符串地址入栈
	call	__printf_chk
	movl	$0, %eax
	leave
	ret
[ ... ]
Tags: ,. 1,268 views
June 5, 2009

这些都是对一个设计良好的类的最基本的要求,每当完成一个类的设计时,都要把这些问题都审视一遍,养成好的习惯。

  1. 构造函数
  2. 数据成员是私有的
  3. 无参数的构造函数
  4. 初始化所有数据
  5. Destructor
  6. 有可能被继承的话一定 destructor 要virtual,否则,尽量不用virtual
  7. Copy Constructor
  8. x=x 能正常工作?(自己赋值给自己)
  9. 逻辑关系运算符?
  10. Copy Constructor/operator= 使用 const reference
  11. 函数参数用reference 还是 const reference 还是 object
  12. 不修改成员的函数一定得要const,否则作为const reference 无法调用。
Tags: ,. 12 views
May 22, 2009

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

  • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。
  • 把任何类型的表达式转换成void类型。
Tags: ,. 31 views
May 11, 2009

Const in Header

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//file header.h
static int global_count;
const int global_const_count = 7;
 
//file source1.cpp
#include "header.h"
 
int main()
{
    return 0;
}
 
//file source2.cpp
#include "header.h"

As we can see, both source1.cpp and source2.cpp include the definition of global_const_count, a const in C++ must default to internal linkage. That is, it is visible only within the file where it is defined and cannot be seen at link time by other translation units. But there won’t be two instances of the const. Normally, the C++ compiler avoids creating storage for a const, but instead holds the definition in its symbol table.

Tags: ,. 14 views
Page 1 of 11