C++错误:没有匹配的构造函数进行初始化

18
在C++的成员逐一赋值中,您可以将一个对象的值设置为同一类的另一个对象。我使用一些值初始化了一个矩形对象,并创建了另一个矩形对象,但将第一个对象的值分配给第二个对象时出现了错误。
为什么会这样?

Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Rectangle {
    private:
        double length;
        double width;
    public:
        Rectangle(double, double);
        double getLength() const;
        double getWidth() const;
};

Rectangle::Rectangle(double l, double w) {
    length = l;
    width = w;
}

double Rectangle::getWidth() const { return width; }
double Rectangle::getLength() const { return length; }

#endif

Rectangle.cpp

#include <iostream>
#include "rectangle.h"
using namespace std;

int main()
{
    Rectangle box1(10.0, 10.0);
    Rectangle box2;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    box2 = box1;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    return 0;
}

编译时出现错误:

skipper~/Desktop/Programming/Memberwise: g++ rectangle.cpp 
rectangle.cpp:7:12: error: no matching constructor for initialization of
      'Rectangle'
        Rectangle box1(10.0, 10.0);
                  ^    ~~~~~~~~~~
./rectangle.h:4:7: note: candidate constructor (the implicit copy constructor)
      not viable: requires 1 argument, but 2 were provided
class Rectangle {
  ^
./rectangle.h:4:7: note: candidate constructor
      (the implicit default constructor) not viable: requires 0 arguments, but 2
      were provided
1 error generated.

答案应该放在答案帖子中,而不是问题帖子中。请避免在帖子中进行社交和元评论。请不要插入“EDIT”或“UPDATE”,只需使您的帖子成为编辑时间的最佳展示即可。 [帮助] [元] [元.se] - philipxy
2个回答

15

在这条线上

Rectangle box2; // no default constructor, error

您正在尝试调用Rectangle的默认构造函数。编译器不再生成这样的默认构造函数,因为您的Rectangle有一个接受2个参数的用户定义构造函数。因此,您需要指定这些参数,例如

Rectangle box2(0,10);

当我编译你的代码时,出现了以下错误:

  

Rectangle.cpp:8:15: error: no matching function for call to 'Rectangle::Rectangle()'       Rectangle box2;

解决方案是为Rectangle创建一个默认构造函数,因为由于您定义的构造函数,它不再自动生成:

Rectangle(); // in Rectangle.h

Rectangle::Rectangle(){} // in Rectangle.cpp (or Rectangle::Rectangle() = default; in C++11)

另一种解决方案(并且更可取,因为它不会使数据未初始化)是向您现有的构造函数分配默认参数。

Rectangle::Rectangle(double l = 0, double w = 0); // only in Rectangle.h

这样做可以使你的类具有默认构造函数。


1
据我所知,每当我创建一个用户定义的构造函数时,我也必须创建一个默认构造函数。在C++中一直都是这样吗? - skipper
@skipper 是的。但是如果您提供了默认参数,您的用户定义构造函数也可以成为默认构造函数,因此无需提供2个不同的构造函数。默认构造函数是任何允许在没有参数的情况下调用的构造函数。有关更多详细信息,请查看这里 - vsoftco

4

如果你没有定义构造函数,编译器会自动生成一个默认构造函数。但是,你已经定义了构造函数,所以如果你想要一个默认构造函数,就必须自己提供它。最简单的方法(可以这样说)是在你的两个参数构造函数中使用默认参数来提供它:

Rectangle(double l=0, double w=0)

此外,您应该像下面所示使用inline关键字,否则可能会出现链接器错误:
inline Rectangle::Rectangle(double l, double w) {
    length = l;
    width = w;
}

inline double Rectangle::getWidth() const { return width; }
inline double Rectangle::getLength() const { return length; }

默认构造函数不应该没有参数吗? - skipper
1
@skipper:默认构造函数应该不带参数调用。所有默认参数都满足此要求。 - Steve
我尝试在rectangle.h中添加默认参数,但无法使其正常工作。然而,当我将类和成员函数定义移动到rectangle.cpp中时,使用默认参数可以正常工作。因此,这是一个解决方案,但并不是真正令人满意的,因为我将来可能会遇到同样的问题,却没有解决方法。 - skipper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接