`
weihe6666
  • 浏览: 440449 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

尽量使用const

    博客分类:
  • C++
 
阅读更多
尽可能的使用const


const:使用const的好处是指定一种语义上的约束----某种对象不能被修改,而作用于变量上,则告诉编辑器和其他程序员:此变量为常量,不可被修改。

一、const作用在变量上:

看下面的例子:
char *p              = "hello";          // 非const指针,
                                         // 非const数据

const char *p        = "hello";          // 非const指针,
                                         // const数据

char * const p       = "hello";          // const指针,
                                         // 非const数据

const char * const p = "hello";          // const指针,
                                         // const数据



怎样判断是const指针还是const数据?

语法并非看起来那么变化多端。一般来说,你可以在头脑里画一条垂直线穿过指针声明中的星号(*)位置,如果const出现在线的左边,指针指向的数据为常量;如果const出现在线的右边,指针本身为常量;如果const在线的两边都出现,二者都是常量。

在指针所指为常量的情况下,有些程序员喜欢把const放在类型名之前,有些程序员则喜欢把const放在类型名之后、星号之前。所以,下面的函数取的是同种参数类型:

class widget { ... };

void f1(const widget *pw);      // f1取的是指向
                                // widget常量对象的指针

void f2(widget const *pw);      // 同f2

因为两种表示形式在实际代码中都存在,所以要使自己对这两种形式都习惯。

二、const的一些强大的功能基于它在函数声明中的应用。在一个函数声明中,const可以指的是函数的返回值,或某个参数;对于成员函数,还可以指的是整个函数。

让函数返回一个常量值经常可以在不降低安全性和效率的情况下减少用户出错的几率。对返回值使用const有可能提高一个函数的安全性和效率,否则还会出问题。

看下面的例子:
#include <iostream>
using namespace std;

class String
{
public:
	String();
	~String();
	String(const char *value);
	const String & operator=(const String & rhs);
	char & operator[](int position);
	const char & operator[]( int position)const;

private:
	char *data;

};


//Default Constructor 
String::String()
{
	data =  new char[1];
	data = '\0';
}


String::~String()
{
   delete []data;
}

String::String(const char *value)
{
	if(value)
	{
		data = new char[strlen(value) + 1];
		strcpy(data,value);
	}
	else
	{
		data =  new char[1];
		data = '\0';
	}

}

const String & String::operator=(const String &rhs)
{
	if(this == &rhs)
		return *this;
	delete [] data;

	data = new char[sizeof(rhs.data)+1];
	strcpy(data,rhs.data);

	return *this;
}

char & String::operator[](int position)
{
	return data[position];
}

const char & String::operator[]( int position ) const
{
   return data[position];
}


int main()
{
	string s1 = "hello";
	cout << s1[0] << endl;                  // 调用非const
	s1[0] = 'w';
	cout << s1[0] << endl;

	const string s2 = "world";
	cout << s2[0] << endl;                  // 调用const

	//s2[0] = 'h';

	return 0;
}



有两个重载操作函数:
char & String::operator[](int position)
{
return data[position];
}

const char & String::operator[]( int position ) const
{
   return data[position];
}

第一个返回类型是char&的引用,第二个返回类型是const的char引用。

问题1:为何第一个返回类型是char&的引用,而不是char

若是char,那么语句:s1[0] = 'w';就不能通过编译,s1[0] =返回一个char类型,没有对一个返回类型为char的赋值,这是不允许的。

问题2:返回类型为const,有何作用?

//s2[0] = 'h';这个语句不能通过编译,是因为要赋值给一个const量,编辑器是不允许的,s2[0] ='h'等价为const data[0] = 'h';

由此看出让函数返回一个常量值经常可以在不降低安全性和效率的情况下减少用户出错的几率。

三、成员函数为const的确切含义是什么??


bitwise constness的坚持者认为,当且仅当成员函数不修改对象的任何数据成员(静态数据成员除外)时,即不修改对象中任何一个比特(bit)时,这个成员函数才是const的。

但是不幸的是很多不遵守bitwise constness定义的成员函数可以修改数据成员,特别是,一个“修改了指针所指向的数据”的成员函数,其行为显然违反了bitwise constness定义,但如果对象中仅包含这个指针,这个函数也是bitwise const的,编译时会通过。这就和我们的直觉有差异:

上面的例子改一改:
operator char *() const { return data;}
const string s = "hello";      // 声明常量对象

char *nasty = s;               // 调用 operator char*() const

*nasty = 'm';                  // 修改s.data[0]

cout << s;                     // 输出"mello"


其输出结果为:mello


四、如何是const成员函数也可以修改数据成员

这就是mutate 关键词的引入。

解决方案很简单:利用c++标准组织针对这类情况专门提供的有关const问题的另一个可选方案。此方案使用了关键字mutable,当对非静态数据成员运用mutable时,这些成员的“bitwise constness”限制就被解除:
class string {
public:

  ...    // same as above

private:
  char *data;

  mutable size_t datalength;      // 这些数据成员现在
                                  // 为mutable;他们可以在
  mutable bool lengthisvalid;     // 任何地方被修改,即使
                                  // 在const成员函数里
}; 

size_t string::length() const
{
  if (!lengthisvalid) {
    datalength = strlen(data);    // 现在合法
    lengthisvalid = true;         // 同样合法
  }

  return datalength;
}








分享到:
评论

相关推荐

    EFFECTIVE C++ 条款03 尽量使用const 思维导图

    EFFECTIVE C++ 条款03 尽量使用const 思维导图 在 C++ 编程中,使用 const 关键字可以提高代码的可读性、可维护性和安全性。本文将详细介绍 EFFECTIVE C++ 的第三条款:尽量使用 const 思维导图。 一、const ...

    c++中const关键字使用详解

    四、类成员函数中的const使用 const关键字在类成员函数中的使用具有特殊含义,它可以声明一个成员函数为常量函数。这意味着该函数不会修改任何成员变量。 ```cpp void fun1() const; // 声明fun1为常量成员函数,...

    C++中const使用说明

    - 尽量广泛使用`const`,但需理解其含义。 - 避免对`const`变量赋值。 - 参数中的`const`推荐使用引用或指针,以减少不必要的拷贝。 - 除非特殊情况,否则不要将函数返回值类型设为`const`对象,因为这限制了...

    C++培训教材1

    * 尽量使用const关键字代替#define指令,以提高代码的可读性和安全性。 * 使用inline关键字可以提高函数的执行效率。 二、避免public接口中的数据成员 * 在public接口中,不要将数据成员暴露出来,以免泄露敏感...

    const和define用法

    const和define用法 在 C/C++ 编程语言中,const 和 #define 都可以用来定义常量,...我们应该尽量使用含义直观的常量来表示那些将在程序中多次出现的数字或字符串,并在 C++ 程序中只使用 const 常量而不使用宏常量。

    effective c++笔记1

    因此,在C++中应该尽量使用const、enum、inline来代替#define,以提高代码的可读性和可维护性。 第3条款:尽可能使用const const关键字可以用于修饰变量、函数参数和返回值,以确保数据的安全和不可修改性。使用...

    More Effective C++(中文版)

    2. **尽量使用const成员函数**: - const成员函数允许我们声明函数不会修改对象的状态,这对于读取操作很有用。使用const成员函数可以提高代码的可读性和效率,因为它避免了不必要的数据复制。 3. **考虑const引用...

    effective c++第三版PDF

    3. **尽量使用const**:const修饰的成员函数表明其不会修改对象状态,有助于提高代码可读性和安全性。 4. **尽可能地声明为const**:包括参数、返回类型和引用,这样能防止意外修改,增加代码的稳定性。 5. **使用...

    Effective C++中文第三版

    2. **尽量使用const**:const关键字能帮助避免意外修改数据,提高代码的健壮性。它可以用在函数参数、成员函数和对象本身上。 3. **考虑使用引用而非指针**:引用提供了一种安全的别名机制,不像指针那样可能为空,...

    EffectiveC++3.

    2. **尽量使用const**:通过声明函数参数或成员为const,可以明确表示该对象不应被修改,提高代码的可读性和安全性。 3. **利用const来实现常量正确性**:常量对象应该只能执行不会改变其状态的操作,const在类接口...

    More Effective c++中文版和Effective c++中文版英文版

    2. 尽量使用const,它能帮助编译器发现潜在错误并优化代码。 3. 避免隐式类型转换,特别是避免将运算符重载设计为隐式转换。 4. 使用const成员函数表明函数不会修改对象状态。 5. 利用初始化而非赋值,以确保对象...

    《Effective C++》中文和《More Effective C++》中文,c++超经典巨著两本全

    1. 尽量使用const:const关键字可以提高代码的清晰性和安全性,防止无意修改数据。 2. 尽量使对象在栈上创建:这样可以避免内存管理的复杂性,并减少潜在的资源泄漏。 3. 用私有构造函数和友元实现单例模式:单例...

    Effective C++ 中英文,mobi格式,适合kindle paperwhite

    2. **尽量使用const**:在函数参数、成员函数声明和对象定义中使用const关键字,可以明确表达代码的不变性,有助于编译器进行优化,并减少错误的可能性。 3. **利用引用而非裸指针**:在大多数情况下,引用提供了一...

    effective C++ second

    4. **常量与引用**:深入分析了常量对象和引用的使用,提倡尽量使用const以提高代码的稳定性,并讨论了const成员函数和const表达式的用法。 5. **面向对象设计**:讨论了继承、多态和抽象类的设计策略,以及虚函数...

    effective C++, more effective C++和effective stl(*.pdf,*.chm)

    1. 尽量使用const:通过const可以明确表示哪些变量是不可修改的,有助于防止意外的修改。 2. 慎用全局变量:全局变量容易导致命名冲突和难以调试的问题,应尽量避免使用。 3. 委托构造函数:利用一个构造函数调用另...

    Effectiv C++和高质量c++编程

    第二条建议则是尽量使用const,以增加代码的清晰度和安全性。书中还提到,应当避免使用全局变量,因为它们可能导致难以预料的副作用。 "More Effective C++" 则是在前一本的基础上,提供了35个更高级的策略和实践。...

    Google C++ Style Guide.zip

    尽量使用const关键字来表示不可修改的变量,以增强代码的清晰度和安全性。 4. **错误处理**:提倡使用异常处理机制而非返回错误代码,以减少错误传播。同时,避免使用空指针(NULL),而是使用nullptr。 5. **函数...

    effective c++

    3. **尽量使用const**:const关键字可以指定函数参数、成员变量或对象本身不可修改,这有助于提高代码的健壮性和可读性。理解const在指针和引用中的用法,以及const成员函数的含义。 4. **理解引用的性质**:引用...

    Effective C++ 中文版-高清扫描版

    2. **尽量使用const**:Meyers提倡广泛使用const关键字来声明常量成员函数和常量引用参数,这可以提高代码的清晰性和安全性,防止无意修改对象的状态。 3. **理解引用的生命周期**:C++中的引用一旦被初始化,就不...

Global site tag (gtag.js) - Google Analytics