关于自定义 class 初始化程序的 C++ 混淆
C++ confusion about initializer of custom class
假设我想要一个名为 Domain2D
的自定义 class。域将由内部向量 Triangle
和一个名为 Boundary2D
的对象组成。 Boundary2D
将由 LineSegment
的列表组成,每个三角形将由三个 V2
对象组成。每个 V2
对象将包含两个坐标。让我们这样做:
下面创建了 V2 class 和这个 class 的构造函数,这样我就可以定义像 V2 vertex = V2 (5,-4);
这样的对象 默认值是 (0, 0)
.
class V2 {
public:
long double x, y;
V2(long double xx = 0, long double yy = 0);
};
V2::V2(long double X, long double Y) {
x = X; y = Y;
}
接下来我需要的是线段:
class LineSegment {
public:
V2 v1, v2;
LineSegment(V2 vv1 = V2(0, 0), V2 vv2 = V2(1, 0));
};
LineSegment::LineSegment(V2 VV1, V2 VV2) {
v1 = VV1; v2 = VV2;
}
默认线段由顶点 (0, 0) 和 (1, 0) 组成。然后我需要一个三角形:
class Triangle {
public:
V2 v1, v2, v3;
Triangle(V2 vv1 = V2(0, 0), V2 vv2 = V2(1, 0), V2 vv3 = V2(0, 1));
};
Triangle::Triangle(V2 VV1, V2 VV2, V2 VV3) {
v1 = VV1; v2 = VV2; v3 = VV3;
}
默认三角形由二维笛卡尔坐标中的标准单纯形组成:(0, 0), (1, 0), (0, 1)
。我们快完成了,我们只需要一个由线段组成的边界:
class Boundary2D {
public:
std::vector<LineSegment> l;
Boundary2D(std::vector<LineSegment> ll = {});
};
Boundary2D::Boundary2D(std::vector<LineSegment> lll) {
l = lll;
}
默认边界是空的({}
),所以如果需要,我们可以立即push_back(...)
。
最后,域由边界和三角形向量组成:
class Domain2D {
public:
std::vector<Triangle> t;
Boundary2D b;
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = Boundary2D({}));
};
Domain2D::Domain2D(std::vector<Triangle> ttt, Boundary2D bb) {
t = ttt; b = bb;
}
现在的问题是:编译器可以接受默认的三角形空向量,但它不理解我对默认空边界的需求,我试图用 Boundary2D bb = Boundary2D({})
初始化它。它说 <function-style-cast>: cannot convert from 'initializer list' to 'Boundary2D'
。我究竟做错了什么?这种创建这样的结构的方法不好吗?如果我希望边界默认为空,那么边界的默认初始值设定项应该是什么样的?谢谢。
供参考,违规行是
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = Boundary2D({}));
它试图用默认参数声明一个构造函数。
仔细研究一下,编译器的输出实际上非常简单。您实际上是在尝试使用 C 样式转换将初始化列表 {}
转换为类型 Boundary2D
的对象。由于没有定义这样的转换运算符,它不起作用
只需将其替换为以下内容即可:
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = {});
假设我想要一个名为 Domain2D
的自定义 class。域将由内部向量 Triangle
和一个名为 Boundary2D
的对象组成。 Boundary2D
将由 LineSegment
的列表组成,每个三角形将由三个 V2
对象组成。每个 V2
对象将包含两个坐标。让我们这样做:
下面创建了 V2 class 和这个 class 的构造函数,这样我就可以定义像 V2 vertex = V2 (5,-4);
这样的对象 默认值是 (0, 0)
.
class V2 {
public:
long double x, y;
V2(long double xx = 0, long double yy = 0);
};
V2::V2(long double X, long double Y) {
x = X; y = Y;
}
接下来我需要的是线段:
class LineSegment {
public:
V2 v1, v2;
LineSegment(V2 vv1 = V2(0, 0), V2 vv2 = V2(1, 0));
};
LineSegment::LineSegment(V2 VV1, V2 VV2) {
v1 = VV1; v2 = VV2;
}
默认线段由顶点 (0, 0) 和 (1, 0) 组成。然后我需要一个三角形:
class Triangle {
public:
V2 v1, v2, v3;
Triangle(V2 vv1 = V2(0, 0), V2 vv2 = V2(1, 0), V2 vv3 = V2(0, 1));
};
Triangle::Triangle(V2 VV1, V2 VV2, V2 VV3) {
v1 = VV1; v2 = VV2; v3 = VV3;
}
默认三角形由二维笛卡尔坐标中的标准单纯形组成:(0, 0), (1, 0), (0, 1)
。我们快完成了,我们只需要一个由线段组成的边界:
class Boundary2D {
public:
std::vector<LineSegment> l;
Boundary2D(std::vector<LineSegment> ll = {});
};
Boundary2D::Boundary2D(std::vector<LineSegment> lll) {
l = lll;
}
默认边界是空的({}
),所以如果需要,我们可以立即push_back(...)
。
最后,域由边界和三角形向量组成:
class Domain2D {
public:
std::vector<Triangle> t;
Boundary2D b;
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = Boundary2D({}));
};
Domain2D::Domain2D(std::vector<Triangle> ttt, Boundary2D bb) {
t = ttt; b = bb;
}
现在的问题是:编译器可以接受默认的三角形空向量,但它不理解我对默认空边界的需求,我试图用 Boundary2D bb = Boundary2D({})
初始化它。它说 <function-style-cast>: cannot convert from 'initializer list' to 'Boundary2D'
。我究竟做错了什么?这种创建这样的结构的方法不好吗?如果我希望边界默认为空,那么边界的默认初始值设定项应该是什么样的?谢谢。
供参考,违规行是
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = Boundary2D({}));
它试图用默认参数声明一个构造函数。
仔细研究一下,编译器的输出实际上非常简单。您实际上是在尝试使用 C 样式转换将初始化列表 {}
转换为类型 Boundary2D
的对象。由于没有定义这样的转换运算符,它不起作用
只需将其替换为以下内容即可:
Domain2D(std::vector<Triangle> tt = {}, Boundary2D bb = {});