通过引用对象构造一个类

时间:2011-11-25 09:58:11

标签: c++ pointers opencv

我正在尝试理解在我正在使用的库中实现的类中使用的构造函数。 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传递到课程中是否有任何优势?为什么指针首先用于保存的复制开销?

4 个答案:

答案 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())