我正在自己学习 Bjarne Stroustrup 的《编程原理》一书,但在定义构造函数时遇到了困难。本题需要使用FLTK图形库构建的界面;一般情况下不用担心那里。我们必须用 Circle 类制作一个笑脸,它没有默认的构造函数 - 常规构造函数接受 (x,y) 点和半径。我希望能够进行一些计算/做其他事情 - 因此尝试在类主体之外为我的笑脸定义构造函数。这不起作用,并且我不断收到错误(来自 Visual Studio)“类“Graph_lib::Circle”不存在默认构造函数。
struct Smiley :public Circle {
Smiley(Point p, int rr);
void draw_lines() const;
void sc(Color c);
Circle l_eye;
Circle r_eye;
};
Smiley::Smiley(Point p, int rr) {
Circle(p, rr);
Circle l_eye(Point(p.x - 50, p.y - 50), rr / 8);
Circle r_eye(Point(p.x + 50, p.y - 50), rr / 8);
}
基本上,上面的方法是行不通的。我认为它出于某种原因试图以某种方式创建一个默认的 Circle,但是找不到它的默认函数(因为我还没有编写一个),然后抛出错误。我已经为这个函数尝试了很多不同的组合,但似乎无法让它不尝试和完善默认值。请注意,如果我在 Smiley::Smiley 中去掉 l_eye 和 r_eye 之前的“Circle”类型,它仍然会抛出错误“在没有适当的operator()或转换函数的情况下调用类类型的对象到指针” -函数类型”。
但是,如果我只是在初始化列表中定义它,它就可以正常工作。
struct Smiley :public Circle {
Smiley(Point p, int rr) : Circle(p, rr), l_eye(Point(p.x - 50, p.y - 50), rr/8), r_eye(Point(p.x + 50, p.y - 50), rr/8) {}
void draw_lines() const;
void sc(Color c);
Circle l_eye;
Circle r_eye;
};
显然,这是一个非常简单的例子。然而,我认为了解这一点对我来说很重要,因为将来很多时候我需要在外部构造函数中实际进行计算。如果有人可以帮助解释问题所在,那就太好了。
最佳答案
声明
Circle(p, rr);
创建一个临时的Circle
对象,该对象未被使用。
然后
Circle l_eye(Point(p.x - 50, p.y - 50), rr / 8);
Circle r_eye(Point(p.x + 50, p.y - 50), rr / 8);
正在创建两个新的对象和变量,与同名的成员变量完全无关。
您得到的错误是因为编译器需要初始化(构造)基类和成员变量l_eye
和r_eye
,作为的一部分>Smiley
构造,并且此初始化是在调用 Smiley
构造函数主体之前完成的。
在某种程度上,你的构造函数:
Smiley::Smiley(Point p, int rr) {
Circle(p, rr);
Circle l_eye(Point(p.x - 50, p.y - 50), rr / 8);
Circle r_eye(Point(p.x + 50, p.y - 50), rr / 8);
}
相当于:
Smiley::Smiley(Point p, int rr)
: Circle(), l_eye(), r_eye() // Default initialization
{
Circle(p, rr);
Circle l_eye(Point(p.x - 50, p.y - 50), rr / 8);
Circle r_eye(Point(p.x + 50, p.y - 50), rr / 8);
}
如果Circle
没有默认构造函数(它似乎没有,否则你不会收到有关它的错误),那么这是根本不可能的。
关于在类体之外定义函数时的 C++ 派生构造函数 - "no default constructor",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64440799/