Chris
Chris

Reputation: 8180

Constructing a class via references to objects

I'm trying to understand the constructor used in a class implemented in a library I am using. The key components of class SequenceAnalyzer look like:

class SequenceAnalyzer {
  protected:
    std::vector<cv::Mat> images_;

  public:
    SequenceAnalyzer( std::vector<cv::Mat> *images = NULL )
    {
        if (images != NULL)
          images_ = (*images);
    }

};

When constructing an instance of this class in my main, I pass it a reference to a vector:

std::vector<cv::Mat> myImages;
SequenceAnalyzer se(&myImages);

Now passing in my images by reference passed their location in memory to the class. But my understanding of the (*images) operator means that their address has been dereferenced and so the = operator then copies the contents.

Is there any advantage in passing myImages into the class in this manner? Why are pointers used in the first place if it doesn't end in saved copying overhead anyway?

Upvotes: 1

Views: 117

Answers (4)

Alessandro Pezzato
Alessandro Pezzato

Reputation: 8802

Passing parameter by pointer (or reference) instead of by value avoid temporary copy. So copy is done only when needed, and not when passing it as a parameter. Another advantage is that you can have a NULL default parameter, without creating a default constructor. In this case the implicit default constructor should do the same.

A more elegant way can be this:

SequenceAnalyzer(const std::vector<cv::Mat>& images) {
  images_ = images;
}

No temporary copy (you're passing by reference) and who uses this is sure images wont be modified.

Upvotes: 0

Sam
Sam

Reputation: 20056

It may be of some help to know that even if you copy the vector, you will copy only the image headers (structure containing type, width, height, etc). Mat objects encapsulate a smart pointer to the data, so a deep copy of the image data happens only when calling specific functions (Mat::copyTo(), Mat::clone())

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385274

When constructing an instance of this class in my main, I pass it a reference to a vector:

std::vector<cv::Mat> myImages;
SequenceAnalyzer se(&myImages);

No, you don't.

& on a type indicates a reference type; & on an expression is the "address-of" operator and yields a pointer! That's why your constructor accepts a pointer, otherwise this would not work.

Now passing in my images by reference [pointer] passed their location in memory to the class. But my understanding of the (*images) operator means that their address has been dereferenced and so the = operator then copies the contents.

Correct.

Is there any advantage in passing myImages into the class in this manner? Why are pointers used in the first place if it doesn't end in saved copying overhead anyway?

Presumably the programmer wanted to avoid the vector being copied twice (once for the argument and again for storage as a member). It's unusual to do that with a pointer rather than a reference, though.


I would have instead written:

class SequenceAnalyzer {
  protected:
    std::vector<cv::Mat> images_;

  public:
    SequenceAnalyzer(const std::vector<cv::Mat>& images = std::vector<cv::Mat>())
       : images_(images) {};
};

Now you have your reference parameter, your default, and also you're initialising properly.

Upvotes: 1

Yakov Galka
Yakov Galka

Reputation: 72519

There isn't any advantage. I would write the same code as:

SequenceAnalyzer( const std::vector<cv::Mat>& images = std::vector<cv::Mat>()) :
    images_(images)
{
}

Now I don't need to worry about pointers:

std::vector<cv::Mat> myImages;
SequenceAnalyzer se(myImages);

Upvotes: 1

Related Questions