C++ 构造函数使用 ":成员变量(形参)" 的形式给类里面成员变量赋值,如果成员变量和形参是指针,那么需要注意的事项
来源:互联网 发布:央视评论网络直播乱象 编辑:程序博客网 时间:2024/06/05 02:56
我先把结论列出来:
当成员变量和形参是指针,最好不要使用:成员变量(形参)
这样的形式。因为你可以不是进行:成员变量 = 形参
这个方向的赋值,你可能是执行:形参 = 成员变量
这个方向的赋值。因为前提,它们都是指针嘛。
今天我遇到了这样的一个错误:
下面的程序,编译是正常通过的,但是运行却不行。(我只是将相关的代码贴了出来)
class PclView{public: PclView(pcl::visualization::PCLVisualizer * &p); void showCloudsLeft(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_source, const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_target);private: pcl::visualization::PCLVisualizer *p;};
PclView::PclView(pcl::visualization::PCLVisualizer * &p):p(p){ vp_1 = 1; vp_2 = 2; // Create a PCLVisualizer object p = new pcl::visualization::PCLVisualizer ("Pairwise Incremental Registration example"); p->createViewPort (0.0, 0, 0.5, 1.0, vp_1); p->createViewPort (0.5, 0, 1.0, 1.0, vp_2); p->removePointCloud ("vp1_target");}void PclView::showCloudsLeft(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_source, const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_target){ p->removePointCloud ("vp1_target"); p->removePointCloud ("vp1_source"); pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> tgt_h (cloud_target, 0, 255, 0); pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> src_h (cloud_source, 255, 0, 0); p->addPointCloud (cloud_target, tgt_h, "vp1_target", vp_1); p->addPointCloud (cloud_source, src_h, "vp1_source", vp_1);// PCL_INFO ("Press Space to begin the registration.\n"); p-> spinOnce();}
当我们在main.cpp
文件中定义了一个上面的类的实例化对象后,然后调用这个类的showCloudsLeft()
方法。编译程序没有问题, 但是运行程序就会出现错误。
int main(void){ pcl::visualization::PCLVisualizer *p; PclView viewer(p); pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_source; pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_target; viewer.showCloudsLeft(cloud_source, cloud_target); return 0;}
上面的程序运行的时候程序会死在showCloudsLeft()
函数里面的p->removePointCloud ("vp1_target");
这段代码。原因是:p
指针为空。
正确的写法:
问题出现在PclView::PclView(pcl::visualization::PCLVisualizer * &p)
这个构造函数里面。
正确的写法有两种:
PclView::PclView(pcl::visualization::PCLVisualizer * &p){ this->p = p; vp_1 = 1; vp_2 = 2; // Create a PCLVisualizer object this->p = new pcl::visualization::PCLVisualizer ("Pairwise Incremental Registration example"); this->p->createViewPort (0.0, 0, 0.5, 1.0, vp_1); this->p->createViewPort (0.5, 0, 1.0, 1.0, vp_2); this->p->removePointCloud ("vp1_target");}
或者:
PclView::PclView(pcl::visualization::PCLVisualizer * &p):p(p){ vp_1 = 1; vp_2 = 2; // Create a PCLVisualizer object this->p = new pcl::visualization::PCLVisualizer ("Pairwise Incremental Registration example"); this->p->createViewPort (0.0, 0, 0.5, 1.0, vp_1); this->p->createViewPort (0.5, 0, 1.0, 1.0, vp_2); this->p->removePointCloud ("vp1_target");}
现在问题就解决了。
但是虽然现在的问题是解决了,但是程序还是有潜在问题的。(现在的程序,还没有达到我们想要的目的。)我们最开始设计这个构造函数,是想将外部通过形参传入的这个指针能够与这个实例化对象里面pcl::visualization::PCLVisualizer * p
指针能够指向同一个东西,然后它们两个都可以去改变这个东西。
但是现在我们并没有做到这一点。我们可以使用下面的代码验证:
int main(void){ pcl::visualization::PCLVisualizer *p; PclView viewer(p); pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_source; pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_target; viewer.showCloudsLeft(cloud_source, cloud_target); p->removePointCloud ("vp1_target"); return 0;}
编译程序不会出现什么问题,但是现在运行,程序就会在main()
函数里面的p->removePointCloud ("vp1_target");
这段代码出现问题。
所以,正真正确的解决办法是:
PclView::PclView(pcl::visualization::PCLVisualizer * &p){ vp_1 = 1; vp_2 = 2; // Create a PCLVisualizer object this->p = new pcl::visualization::PCLVisualizer ("Pairwise Incremental Registration example"); this->p->createViewPort (0.0, 0, 0.5, 1.0, vp_1); this->p->createViewPort (0.5, 0, 1.0, 1.0, vp_2); this->p->removePointCloud ("vp1_target"); p = this->p;}
现在就变成了完美的程序,不会出现问题,也没有潜在的问题。
出现上面的问题的原因
原因很简单,完美的设计思想是:希望两个指针都指向同一个存储空间,但是,实际上两个指针没有指向一个存储空间,一个指针指向了存储空间,而一个是空指针,所以就出现了错误。
- C++ 构造函数使用 ":成员变量(形参)" 的形式给类里面成员变量赋值,如果成员变量和形参是指针,那么需要注意的事项
- 类成员变量中存在引用,const,和指针类型时需要注意的事项
- 类的成员变量偏移指针和成员函数指针
- 类的成员变量偏移指针和成员函数指针 .
- 带有指针成员变量类的拷贝构造函数实现
- python中的类变量、成员变量和成员函数的局部变量使用
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
- 成员函数指针和成员变量指针
- 使用java反射操作类的构造函数,成员变量和成员方法
- 成员变量和成员函数的存储
- C++构造函数对类成员变量初始化,使用初始化列表和构造函数内部直接赋值 的区别
- 多文件多线程断点续传项目练习总结
- Java利用Socket进行远程过程调用
- 转载 同龄人2016年的一篇博文 用来自励
- 数学建模学习笔记
- 利用 pwntools 编写 socket 脚本
- C++ 构造函数使用 ":成员变量(形参)" 的形式给类里面成员变量赋值,如果成员变量和形参是指针,那么需要注意的事项
- 最大公约数与最小公倍数
- 工作项目 17年2月1日 关于迭代法的应用
- 40. Combination Sum II
- Mac快捷键盘记录
- 2017—— 新的一年,新的开始,希望一路从中都有新的收获
- ☆☆☆过来人给嵌入式工程师的十个小建议
- 蓝桥杯练习题P1001(大数乘法)
- HDU4341:Gold miner(分组背包)