我正在尝试理解在我正在使用的库中实现的类中使用的构造函数。 SequenceAnalyzer类的关键组件如下:
class SequenceAnalyzer {
protected:
std::vector<cv::Mat> images_;
public:
SequenceAnalyzer( std::vector<cv::Mat> *images = NULL )
{
if (images != NULL)
images_ = (*images);
}
};
在我的main中构造这个类的实例时,我将它传递给vector:
std::vector<cv::Mat> myImages;
SequenceAnalyzer se(&myImages);
现在通过引用传递我的图像将它们在内存中的位置传递给类。但是我对(* images)运算符的理解意味着它们的地址已被解除引用,因此=运算符然后复制内容。
以这种方式将myImages传递到课程中是否有任何优势?为什么指针首先用于保存的复制开销?
答案 0 :(得分:1)
没有任何优势。我会写相同的代码:
SequenceAnalyzer( const std::vector<cv::Mat>& images = std::vector<cv::Mat>()) :
images_(images)
{
}
现在我不需要担心指针:
std::vector<cv::Mat> myImages;
SequenceAnalyzer se(myImages);
答案 1 :(得分:1)
在我的main中构造这个类的实例时,我将它传递给它 引用向量:
std::vector<cv::Mat> myImages; SequenceAnalyzer se(&myImages);
不,你没有。
类型上的 &
表示引用类型;表达式上的&
是“address-of”运算符并产生一个指针!这就是你的构造函数接受指针的原因,否则这将不起作用。
现在通过
引用传递我的图像[指针] 在内存中传递了它们的位置 上课。但我对(*images)
运算符的理解意味着 他们的地址已被解除引用,因此=
运营商 复制内容。
正确。
将myImages传递给本课程是否有任何优势 方式?如果指针没有结束,为什么首先使用指针 无论如何都节省了复制开销?
据推测,程序员希望避免将矢量复制两次(一次用于参数,另一次用于存储作为成员)。但是,使用指针而不是引用来执行此操作是不寻常的。
我会改为写:
class SequenceAnalyzer {
protected:
std::vector<cv::Mat> images_;
public:
SequenceAnalyzer(const std::vector<cv::Mat>& images = std::vector<cv::Mat>())
: images_(images) {};
};
现在你有了参考参数,默认值,还有正确的初始化。
答案 2 :(得分:0)
通过指针(或引用)而不是值传递参数避免临时复制。因此,仅在需要时才进行复制,而不是在将其作为参数传递时进行。另一个优点是您可以拥有NULL默认参数,而无需创建默认构造函数。在这种情况下,隐式默认构造函数应该执行相同的操作。
更优雅的方式可以是:
SequenceAnalyzer(const std::vector<cv::Mat>& images) {
images_ = images;
}
没有临时副本(你通过引用传递)以及使用它的人确定图像不会被修改。
答案 3 :(得分:0)
知道即使您复制矢量,您也只能复制图像标题(包含类型,宽度,高度等的结构),这可能会有所帮助。 Mat对象封装了一个指向数据的智能指针,因此只有在调用特定函数时才会发生图像数据的深层复制(Mat :: copyTo(),Mat :: clone())