Search code examples
c++classvectorstlstdvector

Do we need to clear a class member of type vector in beginning of the constructor function of the class?


I am trying to understand the class definition of a class in this pdf: http://finance.bi.no/~bernt/gcc_prog/recipes/recipes.pdf (Page 61-62). The part of the code where I have the question is below. The following is the header file:

#ifndef _TERM_STRUCTURE_CLASS_INTERPOLATED_
#define _TERM_STRUCTURE_CLASS_INTERPOLATED_

#include "term_structure_class.h"
#include <vector>
using namespace std;

class term_structure_class_interpolated : public term_structure_class {
private:

    vector<double> times_; // use to keep a list of yields
    vector<double> yields_;
    void clear();

public:

    term_structure_class_interpolated();
    term_structure_class_interpolated(const vector<double>& times, const vector<double>& yields);
    virtual ˜term_structure_class_interpolated();
    term_structure_class_interpolated(const term_structure_class_interpolated&);
    term_structure_class_interpolated operator= (const term_structure_class_interpolated&);

    int no_observations() const { return times_.size(); };
    virtual double r(const double& T) const;
    void set_interpolated_observations(vector<double>& times, vector<double>& yields);

};
#endif

Below is the code file defining the class methods:


#include "fin_recipes.h"

void term_structure_class_interpolated::clear(){

    times_.erase(times_.begin(), times_.end());
    yields_.erase(yields_.begin(), yields_.end());

};

term_structure_class_interpolated::term_structure_class_interpolated():term_structure_class(){clear();};

term_structure_class_interpolated::term_structure_class_interpolated(const vector<double>& in_times,
const vector<double>& in_yields) {

    clear();
    if (in_times.size()!=in_yields.size()) return;
    times_ = vector<double>(in_times.size());
    yields_ = vector<double>(in_yields.size());
    for (int i=0;i<in_times.size();i++) {
        times_[i]=in_times[i];
        yields_[i]=in_yields[i];
    };

};

term_structure_class_interpolated::˜term_structure_class_interpolated(){ clear();};

\\ rest of the code not included here

If you look at the two definitions for the constructor function and the definition of the destructor function, the method clear() is called at the beginning, which as I understand makes the size of the class member vectors zero. I don't understand why is that done? Isn't their size already zero?

My second question is why the parent class (term structure class) is being referenced in the below line:

term_structure_class_interpolated::term_structure_class_interpolated():term_structure_class(){clear();};

The thrid question is: Can't we simply use assignment operator in the other constructor definition to initilise times and yields, instead of copying element by element using for loop, like this?

term_structure_class_interpolated::term_structure_class_interpolated(const vector<double>& in_times,
const vector<double>& in_yields) {

    times_ = in_times;
    yields_ = in_yields;

};

Solution

    1. The clear operation is not necessary. By the time you reach the body of the constructor, the vector objects have been default constructed. A default constructed vector is empty.

    2. That is calling the default base class constructor. If no base class constructor call is present, the default is invoked automatically. An explicit base class constructor call is only required if you wish to call a non-default constructor of the base class. Because the code you posted is invoking the default constructor, it is not technically needed. The compiler will do that automatically.

    3. Yes, and that initialization is usually not done in the constructor body:

    term_structure_class_interpolated::term_structure_class_interpolated(const vector<double>& in_times,
    const vector<double>& in_yields)
      : times_(in_times),
        yields_(in_yields)
    {
    };
    

    This calls the copy constructor of the vector rather than the copy assignment operator. This avoids the auto generated call to the vector default constructor that would be inserted by the compiler if you performed the assignment in the constructor body.

    Note that doing it this way means you can't simply return when the size of the vectors are unequal like the posted code is doing. If that is required, you need to assign the vectors within the constructor body using the copy assignment operator.