C++ 没有用于调用类构造函数的匹配函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31211319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
No matching function for call to Class Constructor
提问by nonremovable
I am practicing my OOP and I have the following classes: Point and Circle. Specifically, Circle has a center Point, and a radius. Here is the relevant code:
我正在练习我的 OOP,我有以下课程:点和圆。具体来说,Circle 有一个中心点和一个半径。这是相关的代码:
// Point.h
class Point
{
public:
Point(double x, double y);
double x() const;
double y() const;
std::string as_string() const;
private:
double x_coord;
double y_coord;
};
// Circle.h
class Circle
{
public:
Circle(const Point& center, double radius);
Point center() const;
double radius() const;
std::string as_string() const;
std::string equation() const;
private:
Point center_pt;
double radius_size;
};
// Circle.cpp
Circle::Circle(const Point& center, double radius)
{
center_pt = center;
radius_size = radius;
}
However, when I try to compile this code, I get the following error:
但是,当我尝试编译此代码时,出现以下错误:
Circle.cpp: In constructor ‘Circle::Circle(const Point&, double)':
Circle.cpp:3: error: no matching function for call to ‘Point::Point()'
Point.h:10: note: candidates are: Point::Point(double, double)
Point.h:8: note: Point::Point(const Point&)
I am not sure how to interpret this error. Is it telling me I need to provide the x_coord and y_coord for the Point parameter in my Circle constructor?
我不确定如何解释这个错误。它是否告诉我需要在我的 Circle 构造函数中为 Point 参数提供 x_coord 和 y_coord?
回答by shuttle87
The member center_pt
is being default initialized and such an operation will call the no arguments default constructor Point()
. This however is not defined in the Point
class and therefore gives you the error you got.
该成员center_pt
被默认初始化,这样的操作将调用无参数默认构造函数Point()
。然而,这不是在Point
类中定义的,因此会给你你得到的错误。
Circle::Circle(const Point& center, double radius)
{
center_pt = center; //<-- this is an assignment
//default init has already occurred BEFORE this point
radius_size = radius;
}
Before you can assign to center_pt
here you need something to assign to. The compiler therefore tries to default initialize center_pt
for you first before trying to do the assignment.
在您分配给center_pt
这里之前,您需要分配一些东西。因此,center_pt
在尝试进行赋值之前,编译器会首先尝试为您默认初始化。
Instead if you use the member initializer listyou can avoid the problem of the default construction followed by assignment:
相反,如果您使用成员初始值设定项列表,则可以避免默认构造后跟赋值的问题:
Circle::Circle(const Point& center, double radius):
center_pt(center),
radius_size(radius)
{
}
When you create a class you are essentially setting aside the memory to store the various members within that class. So imagine center_pt
and radius_size
as places in the memory that those values get stored in for each instance of your class. When you create a class those variables have to get given some default values, if you don't specify anything you get the default constructed values, whatever those are. You can assign values later to those locations but some initialization will always occur at the time of class creation. If you use the initializer list you get to explicitly specify what gets placed in the memory the first time around.
当您创建一个类时,您实际上是在留出内存来存储该类中的各种成员。所以,想象center_pt
并radius_size
在这些值存储在你的类的每个实例的记忆的地方。当你创建一个类时,这些变量必须得到一些默认值,如果你没有指定任何东西,你会得到默认的构造值,无论这些值是什么。您可以稍后为这些位置分配值,但在创建类时总会进行一些初始化。如果您使用初始化列表,您可以明确指定第一次放置在内存中的内容。
By using the member initializer list here your members are being constructed appropriately the first time around. It also has the benefit of saving some unnecessary operations.
通过在此处使用成员初始值设定项列表,您的成员将在第一次被正确构建。它还具有节省一些不必要操作的好处。
回答by Vlad from Moscow
Change the constructor the following way
按以下方式更改构造函数
Circle::Circle(const Point& center, double radius)
: center_pt( center ), radius_size( radius )
{
}
The problem is that if you will not call explicitly the constructor with parameters for class Point
then the compiler tries to call the default constructor of the class to create data member center_pt
of class Circle before you can assign the point within the body of the constructor of class Circle
. But you did not define the default constructor of class Point
and the compiler issued an error.
问题是,如果您不显式调用带有类参数的构造函数,Point
那么编译器会尝试调用类的默认构造函数来创建center_pt
类 Circle 的数据成员,然后您才能在类的构造函数体内分配点Circle
。但是你没有定义类的默认构造函数,Point
编译器发出错误。
The other approach is indeed to define the default constructor for class Point
that for example initilaizes a point with zeroes.
另一种方法确实是为类定义默认构造函数Point
,例如用零初始化一个点。
Take into account that by design of class Point
you can not change data members coord_x
and coord_y
of a created object.Maybe you should redesign the class.
考虑到根据类的设计,Point
您不能更改数据成员 coord_x
和coord_y
创建的对象。也许您应该重新设计类。
回答by Dean P
In trying to construct Circle, you tried to constructa Point using a default constructor:
在尝试构建圈,你试图构建使用默认构造方法的点:
Circle::Circle(const Point& center, double radius)
^
//...Calling default constructor...
...and then assignedit a value:
...然后给它赋值:
center_pt = center;
Given that the default constructor didn't exist, you got the compile-time error.
鉴于默认构造函数不存在,您会收到编译时错误。
Two solutions are:
两种解决方案是:
1)Construct a Point using a member initialisation list:
1)使用成员初始化列表构造一个 Point:
Circle::Circle(const Point& center, double radius): center_pt(center),
radius_size(radius) {
}
2)Define a default constructor for Point:
2)为Point定义一个默认构造函数:
Point::Point(){
}
I am primarily answering this question to place emphasison option 2 as I believe this emphasiswas lacking in the answers above. Sometimes, it is more practical to default construct an object in a givens class parameter list and assign it a value at a later stage. This is encountered a bit in GUI programming in using the Qt framework.
我主要回答这个问题是为了强调选项 2,因为我认为上面的答案缺乏这种强调。有时,在给定的类参数列表中默认构造一个对象并在稍后阶段为其分配值更实用。这是在使用 Qt 框架的 GUI 编程中遇到的一点。
回答by Ami Tavory
This is because you are not initializing the member in the initialization list, but rather assigning to it in the body. Consequently, it is first constructing it using the default ctor, and hence your compiler's complaint.
这是因为您不是在初始化列表中初始化成员,而是在正文中对其进行分配。因此,它首先使用默认 ctor 构造它,因此编译器会抱怨。
Consider changing things to:
考虑将事情更改为:
// Circle.cpp
Circle::Circle(const Point& center, double radius) :
center_pt(center),
radius_size(radius)
{
}
回答by Ed Heal
Change
改变
Circle::Circle(const Point& center, double radius)
{
center_pt = center;
radius_size = radius;
}
to
到
Circle::Circle(const Point& center, double radius) : center_pt(center), radius_size(radius)
{
}
So that it uses the constructor that you have defined for point. Also better for radius as well
以便它使用您为点定义的构造函数。半径也更好