为什么这在c ++构造函数中不起作用

时间:2014-07-03 13:29:30

标签: c++ inheritance constructor destructor

我正在尝试刷新我的c ++,所以我决定用所有构造函数编写一个类,但后来我意识到重用以前定义的构造函数是不可能的(例如:this(arg1,arg2){}就像c#)。

所以我尝试了这个,第一个是头文件,第二个是实现文件:

标题文件:

class Point
{
public:
       int get_x() const;
       void set_x(int);

       int get_y() const;
       void set_y(int);

       Point(int, int);
       Point();
       Point(const Point&);
       ~Point();
private:
        int x_coord, y_coord;

};

实施档案:

int Point::get_x() const
{
    return this->x_coord;
}
void Point::set_x(int x)
{
     this->x_coord = x;
}

int Point::get_y() const
{
    return this->y_coord;
}
void Point::set_y(int y)
{
     this->y_coord = y;
}

Point::Point(int x, int y)
{
  this->set_x(x);
  this->set_y(y);
}

Point::Point(const Point& p)
{
  Point(p.get_x(), p.get_y());
}

// class constructor
Point::Point()
{
  Point(0, 0);
}

// class destructor
Point::~Point()
{
    // insert your code here
}

然后在main.cpp中我这样做:

int main(int argc, char *argv[])
{

    Point a = Point(2, 3);
    Point b = Point(); 
    Point c = Point(a);

    system("PAUSE");
    return EXIT_SUCCESS;
}

只有' a'对象被正确初始化,但其他两个具有这些随机值,并且不会按照我希望的方式进行初始化。

6 个答案:

答案 0 :(得分:3)

这两行

Point(p.get_x(), p.get_y());

Point(0, 0);

不要做你认为他们做的事情:他们不是在被初始化的对象上调用相应的构造函数,而是创建一个新的,不相关的临时对象,它会立即被丢弃。正在创建的Point成员仍然未初始化。

您可以通过定义执行初始化的私有函数来解决此问题。如果您可以访问现代C ++编译器,那么您也可以使用C ++ 11标准:它允许您"chain" constructors

答案 1 :(得分:2)

在此构造函数中

Point::Point()
{
  Point(0, 0);
}

表达式声明

  Point(0, 0);

创建一个Point类型的临时对象,并立即删除它。因此原始对象的数据成员不会被初始化。

复制构造函数存在同样的问题

Point::Point(const Point& p)
{
  Point(p.get_x(), p.get_y());
}

您想要的是以下

Point::Point(int x, int y) : x_coord( x ), y_coord( y )
{
}

Point::Point(const Point& p) : x_coord( p.x_coord ), y_coord( p.y_coord )
{
}

// class constructor
Point::Point() : Point( 0, 0 )
{
}

最后一个构造函数与C#中使用委托的构造函数相同,只是使用类名来命名构造函数而不是关键字this。

考虑到而不是

Point a = Point(2, 3);
Point b = Point(); 
Point c = Point(a);

会更好更简单
Point a(2, 3);
Point b; 
Point c = a;

答案 2 :(得分:1)

Point::Point(const Point& p)
:  Point(p.get_x(), p.get_y())
{
}

Point::Point() 
: Point(0, 0)
{

}

这些是您想要使用的构造函数。 这样,您就可以在所谓的初始化列表中调用其他构造函数。

以前的解决方案只是创建一个未命名的Locale语言环境对象,因为在普通范围内调用Point()会为您创建一个Point对象。

其次,您不能在类构造中安全地使用this指针,因为该类尚未完全初始化,这意味着您只想在get和{set中引用您的类型{1}}方法的名称,而不是this->。例如:

int Point::get_x() const
{
    return this->x_coord;
}

变为

int Point::get_x() const
{
    return x_coord;
}

在旁注和更多信息中 - Point::Point(const Point& p)构造函数称为复制构造函数,在使用=运算符时使用。在下面的情况下:

Point a;
Point b = a;

以上代码将调用您的Point::Point(const Point& p)构造函数。

答案 3 :(得分:0)

使用

Point::Point() : x_coord(0), y_coord(0) {}

答案 4 :(得分:0)

使用初始化列表或从每个构造函数调用一个公共初始化函数:

//initializer list
Point::Point() : x_coord(0), y_coord(0) {}
//common init function (call from constructors)
Point::init(int x, int y) { //perform initialization }

答案 5 :(得分:0)

最好在默认构造函数中使用默认值

Point::Point ( int x = 0, int y = 0 )
    : x_coord ( x ), y_coord ( y )
{}