const经典例子小结

在看这个例子之前,可以先看看:详解C和C++中的constconst和static变量的存放位置这样将会对const有非常全面的了解和认识:

下面我们将通过下面的例子看看const的一些非常不易发觉的错误:

#include<iostream>
using namespace std;

class String
{
public:
	friend ostream& operator<<(ostream& os,const String& str);
    String(char* pstring):pstring_(pstring){ }
	void display(){pstring_ = "hello";cout << pstring_ << endl;}
    char& operator[](int index)const
	{
		return pstring_[index];
	}
private:
    char* pstring_;
};

ostream& operator<<(ostream& os,const String& str)
{
	os << str.pstring_;
	return os;
}

void f( const String&  str)
{
	const_cast<String&>(str).display();
}
void g(String& const str)
{
	String a("world");
	str = a;
}

//void h(String* const str){}
int main()
{
	char a[] = "hello";
	const String str(a);
    String ptr("nihao");
	//const String str("how are you?");
    char& c=str[0]; //call const-function
    c='B'; //modified 'pstring_ '  from outer
	cout << str << endl;
	f(str);
    g(ptr);
	return 0;
}

大家看下面三条语句:

char a[] = "hello";

const String str(a);

char& c=str[0]; //call const-function

c=‘B‘; //modified ‘pstring_ ‘  from outer

我们本来定义了一个常量的String,但是通过这种间接的方法却能够去修改它,为什么呢?然后我们如何避免这种现象呢?

我们的方法就是将返回类型改为常量类型,即:

const char& operator[](int index)const;

这样就保证了类型上的一致。但是,即使返回类型不改为const,那么下面的为什么又不行呢:

const String str("how are you?");

char& c=str[0]; //call const-function

c=‘B‘; //modified ‘pstring_ ‘  from outer

我们这里就必须要弄清楚一件事情,就是对于一个字符串来说,它是保存在常量区的,这里面的数据时不能更改的,此时"how are you?"保存在常量区(只读存储区),而将这个字符串初始化给对象str的时候,相当于是将这个字符串的地址赋给对象的变量pstring_,此时,两者将指向同一个字符串,因此里面的数据是无法更改的。而前面的将一个字符串赋给一个数组则是将其的一个副本附给数组,而这个数组存储在栈中,是能够修改的。

对于函数

void f( const String&  str)

{

const_cast<String&>(str).display();

}

我们可知参数中的const是多余的,因为函数体中又将其强制转换成了非常量变量。

而对于函数g和h参数中的const不仅是无用的,而且也是非法的,因为此时的const修饰的是形参,而不是实参,他们所指向的对象仍然是可以修改的,只能讲非常量参数传递给他们,并且不能被重置。例如:

g(ptr);这条语句之后,ptr的值将会改变成world。



const经典例子小结

时间: 2024-08-27 03:52:16

const经典例子小结的相关文章

【C++系列经典例子】C++默认构造,拷贝,赋值,析构四函数

本例子来自于学习视频,不是原创. 首先,我们已经知道我们创建类时会有四个默认函数(实际是有6个,具体以后再探究) 分别是:(以test类为例子) class test { private: int value; } 1.构造函数: test(int x=0) 2.拷贝构造函数: test(const test& it) 3.赋值函数 test &operator(const test& it) 4.析构函数 ~test() 以下是具体应用四个函数的过程的一个经典例子,能让我们更好的

递归的几个经典例子

注意:构造方法不可递归,否则是无限创建对象; 递归的几个经典例子: 1.HannoiTower 1 import java.util.Scanner; 2 public class HanoiTower{ 3 //level代表盘子个数;三个char类型代表柱子 4 public static void moveDish(int level, char from, char inter, char to){ 5 if(level == 1){ 6 System.out.println("从&qu

小猪的数据结构辅助教程——2.5 经典例子:约瑟夫问题的解决

小猪的数据结构辅助教程--2.5 经典例子:约瑟夫问题的解决 标签(空格分隔): 数据结构 约瑟夫问题的解析 关于问题的故事背景就不提了,我们直接说这个问题的内容吧: 一堆人,围成一个圈,然后规定一个数N,然后依次报数,当报数到N,这个人自杀,其他人鼓掌!啪啪啪, 接着又从1开始报数,报到N又自杀-以此类推,直到死剩最后一个人,那么游戏结束! 这就是问题,而我们用计算机模拟的话,用户输入:N(参与人数),M(第几个人死),结果返回最后一个人! 类似的问题有跳海问题,猴子选王等,下面我们就以N =

信号量基础和两个经典例子

信号量基础和两个经典例子 信号量(semaphore) 用于进程中传递信号的一个整数值. 三个操作: 1.一个信号量可以初始化为非负值 2.semWait操作可以使信号量减1,若信号量的值为负,则执行semWait的进程被阻塞.否则进程继续执行. 3.semSignal操作使信号量加1.若信号量的值小于等于0,则被semWait操作阻塞的进程讲被接触阻塞. ps: semWait对应P原语,semSignal对应V原语. 信号量以及PV原语的C语言定义如下 struct semaphore {

python经典例子

http://wangwei007.blog.51cto.com/68019/1106735  检查Linux系统日志error和mysql错误日志的脚本 http://wangwei007.blog.51cto.com/68019/1102836  pickle http://wangwei007.blog.51cto.com/68019/1045577  python用zipfile模块打包文件或是目录.解压zip文件实例 http://blog.163.com/kefan_1987/blo

storm经典例子的wordcount的实现

storm有个经典的例子wordcount,其实这几乎可以说是大数据的经典例子了,mapreduce也会有这个例子.但是storm给的例子包里的WordCountTopology用到了python的调用,直接用eclipse跑起来的话会报错,这里做了个小改动. 1.WordCountTopology.java package storm.starter; import backtype.storm.Config; import backtype.storm.LocalCluster; impor

小猪的数据结构辅助教程——2.6 经典例子:魔术师发牌问题和拉丁方阵问题

小猪的数据结构辅助教程--2.6 经典例子:魔术师发牌问题和拉丁方阵问题 标签(空格分隔): 数据结构 本节引言: 本节继续带来的是循环链表的两个经典例子,分别是魔术师发牌问题和拉丁方阵问题! 1.魔术师发牌问题 问题描述: 魔术师利用一副牌中的13张黑桃牌,预先将他们排好后叠放在一起,牌面朝下.对观众说:"我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示."魔术师将牌堆最上面的哪张排数为1,把他翻过来正好是黑桃A,将黑桃A从牌堆抽出放在桌子上,第二次数1.2

linux Posix 信号量 三 (经典例子)

本文将阐述一下信号量的作用及经典例子,当中包括“<越狱>寄信”,“家庭吃水果”,“五子棋”,“接力赛跑”,“读者写者”,“四方恋爱”等 首先,讲 semWait操作(P操作)和semSignal操作(V操作)的一些基本原则.(接下来同意称为P,V操作) 1. P操作,s - -,if(s<0)阻塞自己 2. V操作,s++,if(s<=0)唤醒一个其他进程 3. P,V操作时原语(通俗讲,就是执行PV操作时时不能被打打断的) 4. P,V操作总是成对出现的.P:资源申请/分配:V操

javascript经典例子

javascript经典例子  一.验证类 1.数字验证内 1.1 整数 1.2 大于0的整数 (用于传来的ID的验证) 1.3 负整数的验证 1.4 整数不能大于iMax 1.5 整数不能小于iMin 2.时间类 2.1 短时间,形如 (13:04:06) 2.2 短日期,形如 (2003-12-05) 2.3 长时间,形如 (2003-12-05 13:04:06) 2.4 只有年和月.形如(2003-05,或者2003-5) 2.5 只有小时和分钟,形如(12:03) 3.表单类 3.1