【C++】由指针常量和常量指针引发的问题

今天在写一个C++程序的时候,要用到STL的set容器,而且我想让它利用自定义的排序准则来实现自动排序。而且set中元素类型是指向自定义的结构体的指针。结果运行总是出错。


下面先贴出起初的代码:

#include <iostream>
#include <set>

using namespace std;

typedef struct test_t{
	int a;
	int b;
}test;

class PersonalCriterion{
public:
	bool operator()(const test* &obj1,const test* &obj2){
		return obj1->a < obj2->a;
	}
};

int main(){
	set<test*,PersonalCriterion> myset;
	test* obj1 = new test();
	obj1->a = 10;
	obj1->b = 9;
	test* obj2 = new test();
	obj2->a = 5;
	obj2->b = 9;

	myset.insert(obj1);
	myset.insert(obj2);

	return 0;
}

结果在VS2008中编译运行出错,错误信息如下:



显然问题出在这个自定义的仿函数排序准则这里。那么究竟是什么问题呢?错误信息显示这里丢失了限定符,即const。但是我这里参数上明明有const呀,疑惑!


再次仔细看输出的错误信息,不能将参数一从类型1转化到类型2.这两个类型有什么区别呢?答案是const的位置不同:指针常量和常量指针的区别!在有指针的地方,const放在不同的位置会导致完全不同的结果。前一种类型中,const是来修饰指针本身的,即指针常量,它指向的对象确定了之后就不能修改了,即不能修改使得它指向另外一个对象。而第二种类型,const是来修饰指针所指向的类型的,即常量指针,指针本身不是const的,可以修改指向别的对象。但是指针所指向的地址处的内容却不能修改,它是const的。



接下来就可以对代码进行修改了。为了避免出现上述的问题,我们用typedef重新定义了指向自定义结构体的指针类型:



这样就不会出现原来的问题了。修改正确的代码如下:

#include <iostream>
#include <set>

using namespace std;

typedef struct test_t{
	int a;
	int b;
}test;

typedef test* test_ptr;

class PersonalCriterion{
public:
	bool operator()(const test_ptr &obj1,const test_ptr &obj2){
		return obj1->a < obj2->a;
	}
};

int main(){
	set<test_ptr,PersonalCriterion> myset;
	test_ptr obj1 = new test();
	obj1->a = 10;
	obj1->b = 9;
	test_ptr obj2 = new test();
	obj2->a = 5;
	obj2->b = 9;
	test_ptr obj3 = new test();
	obj3->a = 20;
	obj3->b = 48;
	test_ptr obj4 = new test();
	obj4->a = 1;
	obj4->b = 2;
	test_ptr obj5 = new test();
	obj5->a = 3;
	obj5->b = 39;

	myset.insert(obj1);
	myset.insert(obj2);
	myset.insert(obj3);
	myset.insert(obj4);
	myset.insert(obj5);

	set<test_ptr,PersonalCriterion>::iterator iter;
	for (iter = myset.begin();iter != myset.end();++iter)
	{
		cout << (*iter)->a << endl;
	}


	return 0;
}

运行结果:



参考资料:

http://www.cppblog.com/cc/archive/2006/03/12/4045.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有昵称阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值