1

可能重复:
如何为成员使用非默认构造函数?

我有当前的代码:

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;
    }
};

我想这样做:

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

但这不会编译,因为该行ImagePoint point;要求ImagePoint类有一个空的构造函数。替代方案(根据我的阅读)说我应该使用指针:

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

但是,一旦构造函数完成运行,这个指针会指向一个清除的对象吗?如果是这样,我必须制作一份副本image_point吗?这需要一个复制构造函数吗?

4

5 回答 5

10

您需要使用构造函数初始化程序列表:

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

如果可能,您应该更喜欢这个。但是,在某些情况下您必须使用它:

  • 没有默认构造函数的成员(如您所述)
  • 成员参考
  • const会员
于 2012-10-22T15:22:47.370 回答
2

您不需要知道这些事情,因为您不会使用该代码,而只是为了完整性:

一旦构造函数完成运行,这个指针会指向一个清除的对象吗?

image_point是的,当构造函数退出时,参数被销毁。所以你是对的,将指向它的指针存储在对象中并在之后尝试使用它是不正确的。

如果是这样,我是否必须制作 image_point 的副本?

这样做可以,但是您不打算使用此代码的原因是您将其复制到哪里的问题。

这需要一个复制构造函数吗?

是的,但ImagePoint已经有一个复制构造函数,编译器会自动为您生成。

于 2012-10-22T15:42:18.163 回答
1

你所读的是错误的。正确的选择是使用初始化列表

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

顺便说一句,这与私人成员无关,如果他们是公开的,你会遇到同样的问题。

于 2012-10-22T15:23:30.373 回答
1

只需使用构造函数初始化列表:

class TrainingDataPoint 
{
private:
    ImagePoint point;
public:
    TrainingDataPoint(const ImagePoint &imgpt) 
         : point(imgpt)
    {
        // other code here as necessary. point has already been initialized
    }
};
于 2012-10-22T15:25:40.797 回答
1

使用构造函数初始化程序将解决您的问题。

TrainingDataPoint(const ImagePoint& image_point) : point(image_point){
}
于 2012-10-22T17:05:20.557 回答