[英]No matching function for call to Class Constructor
我正在練習我的 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;
}
但是,當我嘗試編譯此代碼時,出現以下錯誤:
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&)
我不確定如何解釋這個錯誤。 它是否告訴我需要在我的 Circle 構造函數中為 Point 參數提供 x_coord 和 y_coord?
成員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;
}
在您可以分配給center_pt
之前,您需要分配一些東西。 因此,編譯器首先嘗試為您默認初始化center_pt
,然后再嘗試進行分配。
相反,如果您使用成員初始值設定項列表,則可以避免默認構造后跟賦值的問題:
Circle::Circle(const Point& center, double radius):
center_pt(center),
radius_size(radius)
{
}
當您創建一個類時,您實際上是在留出內存來存儲該類中的各種成員。 因此,將center_pt
和radius_size
想象為內存中的位置,這些值為類的每個實例存儲在其中。 當你創建一個類時,這些變量必須得到一些默認值,如果你沒有指定任何東西,你會得到默認的構造值,無論這些值是什么。 您可以稍后為這些位置分配值,但在創建類時總會進行一些初始化。 如果您使用初始化列表,您可以明確指定第一次放置在內存中的內容。
通過在此處使用成員初始值設定項列表,您的成員將在第一次被正確構建。 它還具有節省一些不必要操作的好處。
按以下方式更改構造函數
Circle::Circle(const Point& center, double radius)
: center_pt( center ), radius_size( radius )
{
}
問題是,如果您不顯式調用帶有類Point
參數的構造函數,那么編譯器會嘗試調用該類的默認構造函數來創建類 Circle 的數據成員center_pt
,然后您才能在構造函數體內分配該點類Circle
。 但是你沒有定義類Point
的默認構造函數,編譯器發出錯誤。
另一種方法確實是為類Point
定義默認構造函數,例如用零初始化一個點。
考慮到通過類Point
的設計,您不能更改所創建對象的數據成員coord_x
和coord_y
。也許您應該重新設計該類。
在嘗試構建圈,你嘗試使用默認的構造函數構造一個點:
Circle::Circle(const Point& center, double radius)
^
//...Calling default constructor...
...然后給它賦值:
center_pt = center;
鑒於默認構造函數不存在,您會收到編譯時錯誤。
兩種解決方案是:
1)使用成員初始化列表構造一個 Point:
Circle::Circle(const Point& center, double radius): center_pt(center),
radius_size(radius) {
}
2)為Point定義一個默認構造函數:
Point::Point(){
}
我主要回答這個問題是為了強調選項 2,因為我認為上面的答案缺乏這種強調。 有時,在給定的類參數列表中默認構造一個對象並在稍后階段為其分配值更實用。 這是在使用 Qt 框架的 GUI 編程中遇到的一點。
這是因為您不是在初始化列表中初始化成員,而是在正文中為其分配。 因此,它首先使用默認 ctor 構造它,因此編譯器會抱怨。
考慮將事情更改為:
// Circle.cpp
Circle::Circle(const Point& center, double radius) :
center_pt(center),
radius_size(radius)
{
}
改變
Circle::Circle(const Point& center, double radius)
{
center_pt = center;
radius_size = radius;
}
到
Circle::Circle(const Point& center, double radius) : center_pt(center), radius_size(radius)
{
}
以便它使用您為點定義的構造函數。 半徑也更好
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.