在c ++中我试图用点类创建一个三角形类。 java中的正确方法是:
public class Point {
double x, y;
public Point(double x, double y){
this.x=x;
this.y=y;
}
}
public class Triangle {
Point p1,p2,p3;
public Triangle(Point p1, Point p2, Point p3){
this.p1=p1;
this.p2=p2;
this.p3=p3;
}
}
在main中:
Point p1=new Point(0,0);
Point p2=new Point(1,1);
Point p3=new Point(-1,1);
Triangle t1=new Trianle(p1,p2,p3);
在c ++中我有:
class point{
double x1,y1;
public:
point(double x, double y){
x1=x;
y1=y;
}
};
class triangle{
point p1, p2, p3;
public:
triangle(point varp1, point varp2, point varp3){
p1=varp1;
p2=varp2;
p3=varp3;
}
};
在main中:
point p1(-1,1);
point p2(1,1);
point p3(0,0);
triangle t1(p1,p2,p3);
不知怎的,这不起作用,为什么?
.................................................. .................................................. .................................................. .................................................. ..........................................
答案 0 :(得分:3)
它不起作用,因为triangle
构造函数将在分配给它们之前尝试默认构造其point
成员,但point
没有默认构造函数。这是因为您只提供了一个带有2个参数的point
构造函数,因此删除了默认的默认构造函数。
相反,您应该使用成员初始化列表初始化点:
dreieck(point varp1, point varp2, point varp3)
: p1(varp1), p2(varp2), p3(varp3)
{ }
分别使用参数p1
,p2
和p3
初始化每个成员varp1
,varp2
和varp3
,因此避免默认构造。
答案 1 :(得分:2)
在C ++中,成员变量是在构造函数体之前构造的,如果你没有指定它们应该如何构造,那么它们将被默认初始化,所以你的构造函数等同于
triangle(point varp1, point varp2, point varp3)
: p1(), p2(), p3() // <--- default-initialize each member
{
p1=varp1;
p2=varp2;
p3=varp3;
}
现在显而易见的是,构造函数不会将构件创建为构造函数参数的副本,它会将它们创建为默认构造的对象,然后为它们分配新值,并执行point
类需要一个默认的构造函数。
其他答案显示了如何正确执行:使用成员初始化列表。您也应该为point
构造函数执行此操作。使用成员初始化器是在C ++中构造成员变量和基类的惯用方法,而不是在构造函数体中的赋值。对于某些类型的成员变量(reference,const对象和非DefaultConstructible类型),它是 only 方式来初始化成员变量。
答案 2 :(得分:1)
您的point
类未定义(或自动提供)默认构造函数。因为您重载了构造函数,所以未包含编译器生成的构造函数。在triangle
类中,您默认构建了三个point
类型的对象。您将收到错误,因为没有可用的默认构造函数。
您应该明确定义构造函数(并且应该通过 member-initializer list 初始化您的成员),例如:
class point
{
public:
point() : x1(0), y1(0) {}
...
};
此外,如果我们使你的parameritized构造函数使用可选参数,它可以作为默认构造函数。例如:
class point
{
public:
point(double x = 0, double y = 0) : x1(x), y1(y) {}
...
};