1

Possible Duplicate:
How do you use the non-default constructor for a member?

I have the current code:

class ImagePoint {
private:
    int row;
    int col;

public:
    ImagePoint(int row, int col){
        this->row = row;
        this->col = col;
    }

    int get_row(){
        return this->row;
    }

    int get_col(){
        return this->col;
    }
};

And I want to do this:

class TrainingDataPoint{
private:
    ImagePoint point;
public:
    TrainingDataPoint(ImagePoint image_point){
        this->point = image_point;
    }
};

But this wont compile because the line ImagePoint point; requires the ImagePoint class to have an empty constructor. The alternative (from what I have read) says I should use a pointer:

class TrainingDataPoint{
private:
    ImagePoint * point;
public:
    TrainingDataPoint(ImagePoint image_point){
        this->point = &image_point;
    }
};

However, once the constructor has finished running will this pointer point to a cleared up object? If so, do I have to make a copy of the image_point? will this require a copy constructor?

Community
  • 1
  • 1
Aly
  • 15,865
  • 47
  • 119
  • 191

5 Answers5

10

You need to use a constructor initializer list:

TrainingDataPoint(const ImagePoint& image_point) : point(image_point){
}

You should prefer this when possible. However, there are situations when you must use it:

  • members with no default constructors (as you mentioned)
  • member references
  • const members
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
2

You don't need to know these things since you're not going to use that code, but just for completeness:

once the constructor has finished running will this pointer point to a cleared up object?

Yes, the parameter image_point is destroyed when the constructor exits. So you're right, it would be incorrect to store a pointer to it in the object and try to use it after that.

If so, do I have to make a copy of the image_point?

That would do it, but the reason you're not going to use this code is the question of where you would copy it to.

will this require a copy constructor?

Yes, but ImagePoint already has a copy constructor which the compiler generates automatically for you.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

What you have read is wrong. The correct alternative is to use an initialisation list

class TrainingDataPoint{
private:
    ImagePoint point;
public:
    TrainingDataPoint(ImagePoint image_point) : point(image_point){
    }
};

By the way this has nothing to do with private members, you'd get the same issue if they were public.

john
  • 7,897
  • 29
  • 27
1

Just use constructor initializer lists:

class TrainingDataPoint 
{
private:
    ImagePoint point;
public:
    TrainingDataPoint(const ImagePoint &imgpt) 
         : point(imgpt)
    {
        // other code here as necessary. point has already been initialized
    }
};
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
1

Using the constructor initializer will fix your problem.

TrainingDataPoint(const ImagePoint& image_point) : point(image_point){
}
Taryn
  • 242,637
  • 56
  • 362
  • 405
LAP
  • 122
  • 1
  • 4
  • 14