I have been have trouble trying to understand how shared pointers work from the perspective of member variables. There are a lot of good questions on SO that explain shared pointers and how/when to use them (this, this, and this, among others). However, I've been struggling to understand how they work when we are dealing with class instance variables, particularly those that are containers (like std::vector
).
I have a workflow that involves
- Reading data from a file
- Storing that data in a container of a class
- Accessing, modifying, and passing around instances of that class
I am trying to understand if (and where) my code is doing needless copying, or if my passing of a constant reference is good enough. After doing some reading, I am inclined to think that I should be creating the objects once on the heap and passing shared pointers around rather than constant references, but I can't articulate why.
I have pasted parts of my program below in (roughly) their current implementation. My questions are:
- For the
PointCloud
class, should I instead be storing shared pointers toPoint3D
objects in the_data
vector? This way, during the filtering operation, I can populate my_inliers
and_outliers
PointCloud variables by filling their respective_data
member variables with shared pointers to the appropriate Point3D objects? - For
Scene
class and theFilter
class, am I better off with making thePointCloud
type member variables shared pointers toPointCloud
? I am pretty sure my current getter implementations return copies, and thesePointCloud
objects can contain millions ofPoint3D
objects, so they're not small. Would this be better than returning a constant reference (as I do inPointCloud::getData()
?
Ultimately I think the root of my question comes down to: should I do nearly all of my object creation on the heap for these classes and just store shared pointers in my member variables? If so, what would the efficiency improvement be? If not, why not?
Here are some components of my program.
(Note: in reality implementations are not actually all inlined. I just did that here for brevity).
scene.h
#include "pointcloud.h"
#include "point3D.h" // just defines the Point3D class
class Scene
{
private:
// Other member variables...
/** Pointcloud */
PointCloud _pointcloud;
public:
// Public functions
inline PointCloud getPointCloud() const; // Return point cloud
inline void readPoints3D(const std::string &path_to_file);
};
PointCloud Scene::getPointCloud() const { return _pointcloud; }
void Scene::readPoints3D(const std::string &path_to_file)
{
std::ifstream file(path_to_file.c_str());
// Run through each line of the text file
std::string line;
std::string item;
while (std::getline(file, line))
{
// Initialize variables id, x, y, z, r, g, b from file data
Point3D pt(id, x, y, z, r, g, b); // Create Point3D object
_pointcloud.addPoint(pt); // Add point to pointcloud
}
file.close();
}
pointcloud.h
#include "point3D.h"
#include <vector>
class PointCloud
{
private:
/** PointCloud data */
std::vector<Point3D> _data;
public:
// Public member functions
inline std::vector<Point3D> & getData();
inline const std::vector<Point3D> & getData() const;
inline void addPoint(const Point3D &pt);
};
const std::vector<Point3D> & PointCloud::getData() const { return _data; }
std::vector<Point3D> & PointCloud::getData() { return _data; }
void PointCloud::addPoint(const Reprojection::Point3D &pt)
{
_data.push_back(pt); // Add the point to the data vector
}
filter.h
#include "pointcloud.h"
// Removes 3D points from a pointcloud if they don't meet certain conditions
class Filter
{
private:
// Good points that should stay in the pointcloud
PointCloud _inliers;
// Removed points
PointCloud _outliers;
public:
Filter(const PointCloud &pointcloud) // Constructor
void filterPointCloud(); // Filtering operation
inline PointCloud getInliers();
inline PointCloud getOutliers();
}
Filter::Filter(const PointCloud &pointcloud) :
_inliers(pointcloud), _outliers(PointCloud()) {}
PointCloud getInliers() { return _inliers; }
PointCloud getOutliers() { return _outliers; }
driver.cpp
#include "scene.h"
#include "pointcloud.h"
#include "filter.h"
// Some function that writes my pointcloud to file
void writeToFile(PointCloud &cloud);
int main()
{
Scene scene;
scene.readPoints3D("points3D_file.txt");
PointCloud cloud = scene.getPointCloud();
Filter f(cloud);
f.filterPointCloud();
writeToFile(f.getInliers());
writeToFile(f.getOutlier());
}
Aucun commentaire:
Enregistrer un commentaire