C++中const对象引用做为形参

今天在写代码的时候,发现添加了下面的这个函数(update)之后,怎么都编译通不过。大概的原始代码如下:

#include<iostream>
#include<string>

using namespace std;

class SyncScheduler
{
public:
	SyncScheduler(string name):_name(name){}
	string& getName() { return _name; }
private:
	string _name;
};

void update(const string& name)
{
	cout<<name<<endl;
}

void foo(const SyncScheduler& ss)
{
	return update(ss.getName());
}

int main()
{
	SyncScheduler ss("helloworld");
	foo(ss);

	system("pause");
	return 0;
}

   编译器提示下面错误:
main.cpp(22): error C2662: “SyncScheduler::getName”: 不能将“this”指针从“const SyncScheduler”转换为“SyncScheduler &”
1> 转换丢失限定符


   尝试了几种方法后,最后只有将getName函数前后都加上const修饰符后,编译才能通过。
   const string& getName() const { return _name; }
   
   这是什么原因呢?查阅了相关资料后,发现了一些线索。
   "在C++中可以传对象引用,比用指针方便,但是为了避免在函数中对象被修改,需要加const限定符,相应的,在实现对象的成员函数时,也要添加const,这样,因为只有const成员函数才能被const对象调用。"
   先举例说明:

class File
{ 
public: 
	File(string filename,string filepath):_filename(filename),_filepath(filepath) { }
	const string getFileName() const {return this->_filename;}
	string getFilePath() const {return this->_filepath;}
private: 
	string _filename; 
	string _filepath; 
}; 
void test(const File& f) 
{ 
	cout<<"filename is:"<<f.getFileName()<<endl; 
	cout<<"filepath is:"<<f.getFilePath()<<endl; 
} 
int main() 
{ 
	File f("a.out","/root"); 
	test(f); 

	system("pause");
	return 0; 
}

  从上可看到,成员函数前面的const是可选的,但是其后面的const是必须的。如果去掉getFilePath函数后面的const修饰符,编译器会给出下面错误:
  error C2662: “File::getFilePath”: 不能将“this”指针从“const File”转换为“File &”
  这是因为:const File& f 相当于一个const对象。由于const对象在调用成员函数的时候,会将this指针强制转换为const this,所以它将无法找到相应的const getFilePath()函数,并且编译器也无法将一个const的对象转换为一个普通对象来调用这个普通方法getFilePath()。

  那SyncScheduler::getName()函数为何必须在前面加const修饰符呢?先看下面代码:

class File
{ 
public: 
	File(string filename,string filepath):_filename(filename),_filepath(filepath) { }
	const string getFileName() const {return this->_filename;}
	string getFilePath() const  {return this->_filepath;}
private: 
	string _filename; 
	string _filepath; 
}; 

void test1(const string& str)
{
	cout<<"test1 :"<<str<<endl;
}
void test2(const string str)
{
	cout<<"test2 :"<<str<<endl;
}


int main() 
{ 
	File f("a.out","/root"); 
	
	test1(f.getFileName());
	test2(f.getFileName());

	test1(f.getFilePath());
	test2(f.getFilePath());

	const string& ss = f.getFilePath();
	cout<<"ss  is:"<<ss<<endl;

	system("pause");
	return 0; 
}

运行结果如下:
test1 :a.out
test2 :a.out
test1 :/root
test2 :/root
ss   is:/root
Press any key to continue . . .
   在上面的结果中可看出,函数前面的const是非必须的。但是,为何SyncScheduler::getName()需要呢。不同之处在于getName返回的是一个引用!为了确保成员_name不会被改变,它的引用者必须也是const类型的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值