今天在写一个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

【C++】由指针常量和常量指针引发的问题相关推荐

  1. C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针

    1. 什么是指针变量? 指针变量是专门有一个变量来存放指针. int main(int argc, char *argv[]) {int a = 10;int *p = &a; //通过取地址 ...

  2. 常引用、常量指针、指针常量、指向常量的常指针、空指针与野指针解释

    1.一.基础知识 引用并非对象 引用必须初始化 引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起 类型要严格匹配 int &a = 10; //错误:引用类型的初始值必须是 ...

  3. 常量指针与指向常量的指针

    这两个概念经常很容易混淆,下面简单分析一下 1.常量指针: int * const p   : const p 就是一个常量,然后再看*,可以看出是一个常量类型的指针,即int类型的常量指针.不能修改 ...

  4. [C++] 指向常量的指针 VS 指针类型的常量

    指向常量的指针 VS 指针类型的常量 const 修饰指针时的位置不同,作用也不相同. 1. 指向常量的指针 不能通过指向常量的指针改变所指对象的值,但指针本身可以改变,可以指向另外的对象. 例: i ...

  5. [C++基础]018_常量指针和指向常量的指针

    先来看一下什么是常量指针,什么是指向常量的指针吧! 1. 常量指针定义 1 int * const ptr = new int(); 2. 指向常量的指针 1 const int* ptr; 上面已经 ...

  6. 【错误记录】C 语言中通过指针操作字符串常量出错记录 ( 只有 栈内存 或 堆内存 中的数据才能通过指针修改 | 不要通过指针修改常量区的字符串 )

    文章目录 一.报错记录 二.修改方案 一.报错记录 执行下面的代码 , 报错如下 : 执行的错误代码 : #include <stdio.h> #include <stdlib.h& ...

  7. 【C 语言】字符串 一级指针 内存模型 ( 指定大小字符数组 | 未指定大小字符数组 | 指向常量字符串的指针 | 指向堆内存的指针 )

    文章目录 一.字符串 一级指针 内存模型 1.指定大小字符数组 2.未指定大小字符数组 3.指向常量字符串的指针 4.指向堆内存的指针 一.字符串 一级指针 内存模型 #include <std ...

  8. C++ 指向常量的指针与指针类型的常量

    (1)声明指向常量的指针时,不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象. #include<iostream>using namespace std;int m ...

  9. c++ 指针常量,常量指针

    当const遇到指针 一般来说,const修饰指针可以分为下面的集中情况. 描述 例子 含义 备注 const在*的左边 const int *b=&a; int const *b=& ...

最新文章

  1. 解决redhat的未注册问题
  2. 数据分析学习笔记——数据可视化
  3. 生成msk文件的用处_Yotta企业云盘“小”功能大用处企业办公好伙伴
  4. 李连杰年度巨作霍元甲主题曲:周杰伦唱
  5. [css] 说说你对设备像素比的理解
  6. Vue自定义组件封装及使用Excel
  7. 阿里云Ubuntu系统部署K8s集群
  8. 机械制造技术基础【4】
  9. 学数学,读原著,勤思考,效果好
  10. 别让学历限制你,你可能是AI领域的下一个巨星
  11. 淘口令解析api接口/淘口令解密还原api接口/淘口令短链接搜索商品详情接口,API接口获取方案
  12. 创建Windows Phone内核模式驱动
  13. 创建一个Date类,具有三个整型成员变量year,month,day,具有三个成员方法setDate,isLeapYear,print
  14. 中国剩余定理 (51nod 1079)
  15. 位图文件, JPG格式,PNG格式
  16. 信息学奥赛 python 教程_Python在信息学竞赛中的运用及Python的基本用法(详解)
  17. wampserver在线但localhost打不开 解决方法
  18. FPGA实现ADC采样芯片ADS8688的采样
  19. 程序养身:初学者如何学瑜伽
  20. 【BABY夜谈大数据】神经网络

热门文章

  1. linux那些事之zero page
  2. caffe prototxt 可视化工具
  3. jQuery的实现原理
  4. [JetBrains Rider] 在保存文件时自动更新文件头的方法
  5. Ubuntu系统显卡驱动、CUDA、CUDNN安装(二CUDA和CUDNN)
  6. 返回顶部:js代码篇
  7. phpcms留言板功能的实现
  8. MCMS 基于SpringBoot 2架构
  9. Oreo授权系统V1.0.6公益开源版本
  10. OREO免费授权系统源码