本文用于记录在使用PointCloud和PointCloud::Ptr时,等号复制、函数传参以及copyPointCloud复制,这几种方法复制后,旧的变量修改是否会影响所复制的变量。仅用于记录,不保证准确。【转载请注明出处】
1. 函数调用
测试了四种函数参数,分别是Ptr类型,PointCloud类型,PointCloud的引用,以及const引用:
void func_ptr(MyPointCloud::Ptr pc){
pc->resize(0);
}
void func_pointcloud(MyPointCloud pc){
pc.resize(0);
}
void func_ref(MyPointCloud& pc){
pc.resize(10);
}
void func_pointcloud_ref(const MyPointCloud& pc){
// pc.resize(0); // Error! cannot change size.
}
测试方法和结果如下:
MyPointCloud::Ptr pc (new MyPointCloud()), pc2(new MyPointCloud());
MyPointCloud pc3, pc4;
cout<<"================ Function test ================" <<endl;
string filename = "mesh.pcd";
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
cout << "------- Test 1. Using Ptr" << endl;
func_ptr(pc);
cout << "after: " << (*pc).size() << endl; // 被修改了,为0
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
cout << "------- Test 2.1 Using pointcloud but input *ptr" << endl;
func_pointcloud(*pc);
cout << "after: " << (*pc).size() << endl; // 未被修改,依旧为12500
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
cout << "------- Test 2.2 Using pointcloud but input pointcloud" << endl;
func_pointcloud(pc3);
cout << "after: " << pc3.size() << endl; // 未被修改,依旧为12500
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
cout << "------- Test 3. Using ref pointcloud" << endl;
func_ref(*pc);
cout << "after: " << (*pc).size() << endl; // 被修改了,为10
func_ref(pc3);
cout << "after: " << pc3.size() << endl; // 被修改了,为10
结论:使用Ptr或引用&,函数内修改会改变实参;而直接PointCloud则不会改变实参。
2. 等号复制
cout << "================ Operator= test ================" << endl;
cout << "------- Test 1. Copy pointer to pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pc2 = pc;
pc->resize(0);
cout << "Pc2: " << pc2->size() << endl; // 被修改了,为0
cout << "------- Test 2. Copy *pointer to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
*pc2 = *pc;
pc->resize(0);
cout << "Pc2: " << pc2->size() << endl; // 被修改了,为0
cout << "------- Test 3. Copy *pointer to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pc3 = *pc;
pc->resize(0);
cout << "Pc3: " << pc3.size() << endl; // 没有被修改
cout << "------- Test 4. Copy value to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pc4 = pc3;
pc3.resize(0);
cout << "Pc4: " << pc3.size() << endl; // 被修改了,为0
cout << "------- Test 5. Copy value to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
*pc = pc3;
pc3.resize(0);
cout << "Pc: " << pc->size() << endl; // 没有被修改
结论:指针和指针之间,无论是指针本身用等号,还是指针内容用等号,本质是同一块数据;PointCloud和PointCloud也是如此。但用指针数据赋给非指针,或反过来,则使用两块内存。
3. copyPointCloud函数
pcl提供了copyPointCloud函数用于点云复制,那么再测一下这个是不是“深度拷贝”
cout << "================ Copy Function test ================" << endl;
cout << "------- Test 1. Copy *pointer to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pcl::copyPointCloud(*pc, *pc2);
pc->resize(0);
cout << "pc2: " << pc2->size() << endl; // 被修改了,为0
cout << "------- Test 2. Copy *pointer to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, *pc);
pcl::copyPointCloud(*pc, pc3);
pc->resize(0);
cout << "pc3: " << pc3.size() << endl; // 没有被修改
cout << "------- Test 3. Copy value to *pointer" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::copyPointCloud(pc3, *pc);
pc3.resize(0);
cout << "pc: " << pc->size() << endl; // 没有被修改
cout << "------- Test 4. Copy value to value" << endl;
pcl::io::loadPCDFile<MyPoint>(filename, pc3);
pcl::copyPointCloud(pc3, pc4);
pc3.resize(0);
cout << "pc4: " << pc4.size() << endl; // 没有被修改
结论:用指针的数据时,使用相同内存;其他情况,指针给变量,或变量给变量,变量给指针,都是两块不同的区域。
4. 小结
之前每次写函数调用和等号复制时,都要纠结到底是共用同一块内存,还是有深拷贝。如今算是测试明白了。
完整测试代码:https://github.com/LarryDong/csdn_codes/tree/main/pointcloud_copy