1.关于const指针
如果关键字const出现在星号左边,表示被指物为常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两都都是常量。
注意被指物是常量时,以下两种写法意义相同:
const int *p;
int const *p;
2.const成员函数
const成员函数不能修改类的数据成员,也就是说,这些函数是“只读”函数。在C++中,const对象只能调用const成员函数。但构造函数和析构函数对这个规则例外,它们从不定义为常量成员,但可被常量对象调用。
这一类成员函数这所以重要,基于两个理由。第一、它们使class接口比较容易被理解。这是因为,得知哪个函数可以改动对象内容而哪个函数不行,很是重要。第二、它们使用"操作const对象"成为可能。
许多人漠视一件事实:两个成员函数如果只是常量性的不同,可以被重载。考虑以下class,用来表现一大块文字:
TextBlock tb("Hello");
std::cout << tb[0]; //调用non-const TextBlock::operator[]
const TextBlock ctb("World");
std::cout << ctb[0]; //调用const TextBlock::operator[]
3.关键字mutable
mutable关键字可以释放掉non-const约束,使得const成员函数可以访问non-const成员变量。
4.在const和non-consst成员函数中避免重复
在上面的TextBlock中,对[]操作符重载的两函数有相同的函数体,所以我们可以通过non-const operator[]调用其const兄弟,下面是代码:
上面的代码中使用了两次转型,第一次用来为*this添加const(使接下来的调用erator[]时得以调用const版本),第二次则是从const operator[]]的返回值中移除const。
更值得了解的是,反向做法-令const版本调用non-const版本以避免重复-并不是你该做的事。记住,const成员函数承诺绝不改变其对象的逻辑状态,non-const成员函数却没有这般承诺。
c++中,const默认使用内部链接。
内连接:编译器只对正被编译的文件创建存储空间,别的文件可以使用相同的表示符或全局变量.C/C++中内连接使用static关键字指定。
外连接:所有被编译过的文件创建一片单独存储空间.一旦空间被创建,连接器必须解决对这片存储空间的引用.全局变量和函数使用外部连接.通过extern关键字声明,可以从其他文件访问相应的变量和函数。
来看下面一段代码:
如果关键字const出现在星号左边,表示被指物为常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两都都是常量。
注意被指物是常量时,以下两种写法意义相同:
const int *p;
int const *p;
2.const成员函数
const成员函数不能修改类的数据成员,也就是说,这些函数是“只读”函数。在C++中,const对象只能调用const成员函数。但构造函数和析构函数对这个规则例外,它们从不定义为常量成员,但可被常量对象调用。
这一类成员函数这所以重要,基于两个理由。第一、它们使class接口比较容易被理解。这是因为,得知哪个函数可以改动对象内容而哪个函数不行,很是重要。第二、它们使用"操作const对象"成为可能。
许多人漠视一件事实:两个成员函数如果只是常量性的不同,可以被重载。考虑以下class,用来表现一大块文字:
class TextBlock{
public:
TextBlock(char* str):text(str)
{
}
const char& operator[] (std::size_t position) const
{
return text[position];
}
char& operator[] (std::size_t position)
{
return text[position];
}
private:
std::string text;
};
TextBlock的operator[]可被这么使用:
TextBlock tb("Hello");
std::cout << tb[0]; //调用non-const TextBlock::operator[]
const TextBlock ctb("World");
std::cout << ctb[0]; //调用const TextBlock::operator[]
3.关键字mutable
mutable关键字可以释放掉non-const约束,使得const成员函数可以访问non-const成员变量。
4.在const和non-consst成员函数中避免重复
在上面的TextBlock中,对[]操作符重载的两函数有相同的函数体,所以我们可以通过non-const operator[]调用其const兄弟,下面是代码:
class TextBlock{
public:
TextBlock(char* str):text(str)
{
}
const char& operator[] (std::size_t position) const
{
//do others
return text[position];
}
char& operator[] (std::size_t position)
{
return const_cast<char&>(
static_cast<const TextBlock&>(*this)[position]
);
}
private:
std::string text;
};
上面的代码中使用了两次转型,第一次用来为*this添加const(使接下来的调用erator[]时得以调用const版本),第二次则是从const operator[]]的返回值中移除const。
更值得了解的是,反向做法-令const版本调用non-const版本以避免重复-并不是你该做的事。记住,const成员函数承诺绝不改变其对象的逻辑状态,non-const成员函数却没有这般承诺。
5.const在c和c++中的区别
c++中的const正常情况下编译期的常量,编译器并不为const分配空间。而在c中,const是一个不能被改变的变量,占用存储空间,所以编译器不知道编译时的值。数组定义时下标必须为常量,比如下面的代码在c++中正确,但在c中编译通不过。
const int n = 10;
char str[10];
c++中,const默认使用内部链接。
内连接:编译器只对正被编译的文件创建存储空间,别的文件可以使用相同的表示符或全局变量.C/C++中内连接使用static关键字指定。
外连接:所有被编译过的文件创建一片单独存储空间.一旦空间被创建,连接器必须解决对这片存储空间的引用.全局变量和函数使用外部连接.通过extern关键字声明,可以从其他文件访问相应的变量和函数。
来看下面一段代码:
//header.h
const int test = 1;
//test1.cpp
#include "header.h"
int main()
{
printf("in test1:%d\n",test);
}
//test2.cpp
#include "header.h"
void print()
{
printf("in test2:%d\n",test);
}
上面代码在c++中可以被正确编译,但是在c中确出现重复定义的错误。
摘自:Effective C++、http://tech.e800.com.cn/articles/2009/722/1248229886744_1.html
2012-04-10
ps:关于上面的第5点的一些补充
其实const的全局变量就相当于默认添加了static关键字,若要在其它文件中可以使用,可以使用extern关键字显式声明:
//a.cpp
extern const int i=0;//需要显示指定extern
//b.cpp
extern const int i;
cout < <i;//OK