简体   繁体   English

C ++类错误信息:没有匹配的调用函数

[英]C++ class error message: no matching function for call

My program is supposed to calculate the surface area and volume of a box. 我的程序应该计算盒子的表面积和体积。 I am to have the following functions: setHeight, setWidth, setLength, getVolume, getSurfaceArea. 我要具有以下功能:setHeight,setWidth,setLength,getVolume,getSurfaceArea。

When I compile my program I get the following error message: 编译程序时,出现以下错误消息:

boxMain.cpp: In function ‘int main()’:
boxMain.cpp:21: error: no matching function for call to 'Box::getVolume(double&, double&, double&)’
Box.hpp:20: note: candidates are: double Box::getVolume()
boxMain.cpp:23: error: no matching function for call to ‘Box::getSurfaceArea(double&, double&, double&)’
Box.hpp:21: note: candidates are: double Box::getSurfaceArea()

Based on my searches on this site, most answers seem to suggest that the default constructor doesn't exit or isn't working. 根据我在该站点上的搜索,大多数答案似乎都暗示默认构造函数不会退出或无法正常工作。 I don't know if that is my issue as well, but I wrote the code for my default constructor according to textbook, so I have trouble figuring out what I did wrong. 我也不知道这是否也是我的问题,但是我根据课本为我的默认构造函数编写了代码,因此我很难弄清楚自己做错了什么。

The missing lines in my code below are just the descriptions and comments that I removed. 我下面的代码中缺少的行仅仅是我删除的描述和注释。

Any help would be appreciated! 任何帮助,将不胜感激! Thank you all so much in advance. 提前谢谢大家。

Here is my .hpp file: 这是我的.hpp文件:

 #include <iostream>
 #ifndef Box_HPP
 #define BOX_HPP

 class Box {

 private:
    double h, w, l;
    double height, width, length;

 public:
    void setHeight(double h);
    void setWidth(double w);
    void setLength(double l);
    double getVolume();
    double getSurfaceArea();
    Box();
 };

Here is my function .cpp file: 这是我的功能.cpp文件:

 #include <iostream>
 #include <iomanip>
 #include "Box.hpp"

 double height;
 double width;
 double length;

 Box::Box() {
    height = 1.0;
    width = 1.0;
    length = 1.0;
 }

 void setHeight(double h) {
    if(h < 0) {
       std::cout << "Error. Height must be positive."
                 << std::endl;
    }
    else {
    height = h;
    }
 }

 void setWidth(double w) {
    if(w < 0) {
       std:: cout << "Error. Width must be positive."
                  << std::endl;
    }
    else {
    width = w;
    }
 }

 void setLength(double l) {
    if(l < 0) {
       std::cout << "Error.  Length must be positive."
                 << std::endl;
    }
    else {
    length = l;
    }
 }

 double getVolume() {
    return (height * width * length);
 }

 double getSurfaceArea() {
    return (2.0 * length * height + 2.0 * width * height);
 }

Here is my main .cpp file: 这是我的主要.cpp文件:

 #include <iostream>
 #include <fstream>
 #include "Box.hpp"

 int main() {
     Box box1;
     double h, w, l;

     std::cout << "Enter height" << std::endl;
     std::cin >> h;
     std::cout << "Enter width" << std::endl;
     std::cin >> w;
     std::cout << "Enter length" << std::endl;
     std::cin >> l;

     void setHeight(double h);
     void setWidth (double w);
     void setLength (double l);

     std::cout << "volume: "
          << box1.getVolume(h, w, l) << std::endl;
     std::cout << "surface: "
          << box1.getSurfaceArea(h, w, l) << std::endl;

     return 0;
 }

Box::getVolume is declared as taking no parameters, but in line 21 you call it with 3 arguments: Box::getVolume被声明为不带任何参数,但是在第21行中,您使用3个参数对其进行了调用:

box1.getVolume(h, w, l)

Use simply box1.getVolume() instead. 只需使用box1.getVolume() Similarly for Box::getSurface() . Box::getSurface()类似。

Also, use Box:: in front of all member function definitions, like void Box::setHeight(double h) {...} , otherwise you end up defining free standing functions and you'll get linker errors since the member functions end up not defined. 另外,在所有成员函数定义前使用Box:: ,例如void Box::setHeight(double h) {...} ,否则最终将定义独立的函数,并且由于成员函数结束而导致链接器错误没有定义。

vsoftco's answer is mostly correct so I have up voted him, although I feel it would be good to add some more information to the answer to help explain it a bit better as well as help clean up several other issues you have here. vsoftco的答案基本上是正确的,所以我对他投了赞成票,尽管我觉得最好在答案中添加一些信息,以更好地说明问题,并帮助您清理此处遇到的其他问题。

The error you had clearly explains the problem if you look at it. 如果您查看该错误,则可以清楚地解释该问题。 It mentions boxMain.cpp in the function int main() as having the problem. 它在int main()函数中提到boxMain.cpp就是有问题。 It further gives you the line number and mentions that there is "no matching function" for the "call" and in both instances notes the call as well as the possible candidates, which in this case is the methods without parameters. 它还为您提供了行号,并提到“调用”没有“匹配功能”,并且在两种情况下都记录了调用以及可能的候选对象,在这种情况下,这是没有参数的方法。

with that aside here are some other tips that may help you avoid further frustration: 除了这些,这里还有其他一些技巧可以帮助您避免进一步的沮丧:

  1. Prefer forward declarations instead of includes in your header files. 优先使用前向声明,而不要包含在头文件中。 In your case you don't need #include <iostream> at all in your box.hpp. 在您的情况下,您的box.hpp中根本不需要#include <iostream> The reason is that anything in your header is effectively leaked into any files that include your header. 原因是标题中的所有内容实际上都会泄漏到包含标题的任何文件中。 This is mainly to help reduce circular dependancies as well as shorten compile times when making changes. 这主要是为了减少循环依赖,并缩短进行更改时的编译时间。 The Pimpl Idiom is an example pattern used with this mantra. Pimpl Idiom是此口头禅使用的示例模式。 I would not recommend using naked pointers, however, instead stick with RAII types such as smart pointers or plain references. 但是,我不建议使用裸指针,而应该坚持使用RAII类型,例如智能指针或纯引用。

  2. You either didn't paste all of your code or your include guard is wrong. 您要么没有粘贴所有代码,要么您的include Guard错误。 You need a closing #endif in your header. 您需要在标题中添加一个#endif结束#endif

  3. You should use a convention to name your member variables to avoid conflicts and keep your large .cpp files easier to read. 您应该使用约定来命名成员变量,以避免冲突,并使大型.cpp文件更易于阅读。 This is a preference more then a rule but it helps. 这比规则更重要,但这很有帮助。 Something like _height , mHeight , _mHeight rather then height . _heightmHeight_mHeight而不是height Lower case camel style variable names are common for locals and parameters. 小写的骆驼样式变量名称对于本地变量和参数是通用的。 It also looks like you really don't need the h,w,l members at all. 看起来您真的真的不需要h,w,l成员。

  4. You should probably use assert for your error handling so as to optimize it out during release builds. 您可能应该使用assert进行错误处理,以便在发布版本期间对其进行优化。 That is of coarse unless you are intending to show the end user the error message. 除非您打算向最终用户显示错误消息,否则这很粗糙。 You may also consider using std::cerr instead. 您也可以考虑使用std :: cerr代替。

  5. The height , width , length variables in your .cpp are also extraneous and do not do what you think. .cpp中的heightwidthlength变量也是无关紧要的,不会按照您的想法做。

  6. You should use an initialization list in your constructor instead of doing the simple work of assigning to variables in the body. 您应该在构造函数中使用初始化列表,而不要简单地为主体中的变量赋值。 There are several special situations as well but this can get you started. 有几种特殊情况很好,但这个可以让你开始。 ex: Box::Box() : height(1.0), width(1.0), length(1.0){} 例如: Box::Box() : height(1.0), width(1.0), length(1.0){}

  7. The only method in the cpp you fully qualified with Box:: is the constructor. 使用Box::完全限定的cpp中唯一的方法是构造函数。 You need to do that with all the methods as well. 您还需要使用所有方法来执行此操作。 ex: double Box::getVolume() 例如: double Box::getVolume()

  8. You are also not calling the correct methods in your main function (in fact you are not calling methods at all. You are basically forward declaring them.) you should be using an object to invoke the methods. 您还没有在main函数中调用正确的方法(实际上您根本没有在调用方法。基本上是在向前声明它们。)您应该使用一个对象来调用方法。 This is why you didn't see a complaint in the error log about missing Box:: 这就是为什么您没有在错误日志中看到有关缺少Box::的投诉的原因Box::

There is one major error in your header file that has nothing to do with your class's declaration, but has to do with the header during the pre-compilation stage. 头文件中有一个主要错误与您的类的声明无关,但与预编译阶段的头有关。 Your header guard is not correct as you have first have your #include <iostream> before the guard; 您的标头防护不正确,因为您必须先将#include <iostream>置于防护之前; this should be after the guard. 这应该在警卫之后。 Second your #ifndef CLASS_NAME does not match your #define CLASS_NAME and you are missing the matching #endif at the bottom of your header file. 其次,您的#ifndef CLASS_NAME与您的#define CLASS_NAME不匹配,并且您在头文件底部缺少匹配的#endif I will remove the #include <iostream> since it is not needed. 我将删除#include <iostream>因为它不是必需的。 The reason I am doing this is because if a user enters a value that is less than or equal to zero it will be set to a default value of 1. So there is no need to print out any error messages for this class. 我这样做的原因是因为如果用户输入的值小于或等于零,它将被设置为默认值1。因此,无需为此类打印任何错误消息。

Your class is close to what you need. 您的课程接近您的需求。 There are a few things that would help to improve your class and maybe this will help. 有几件事可以帮助改善您的课堂,也许这会有所帮助。

Box.h 盒子

#ifndef BOX_H
#define BOX_H

class Box {
private:
    double m_width;
    double m_length;
    double m_height;

    double m_volume;
    double m_surfaceArea;

public:
    Box(); // Default Constructor
    Box( double width, double length, double height );
    // virtual ~Box(); // Default Okay

    void setWidth( double width );
    void setLength( double length );
    void setHeight( double height );

    double getWidth() const; 
    double getLegnth() const;
    double getHeight() const;

    double getVolume() const;
    double getSurfaceArea() const;

private:
    // If You Need Either The Copy Constructor Or The Assignment Operator
    // Remove Them From The Private Section Into The Public Section 
    // Where You May Need To Implement Them Where The Default May Not Be Appropriate
    Box( const Box& c ); // Not Implemented 
    Box& operator=( const Box& c ); // Not Implemented

    void calculateVolume();
    void calculateSurfaceArea();

}; // Box

#endif // BOX_H

Box.cpp Box.cpp

#include "Box.h"

// -------------------------------------------------------------------------
// Box() - Default Box Will Have a 1 x 1 x 1 Dimension
Box::Box() :
m_width( 1.0 ),
m_length( 1.0 ),
m_height( 1.0 ),
m_volume( 0.0 ),
m_surfaceArea( 0.0 ) {
    calculateVolume();
    calculateSuraceArea();
} // Box

// -------------------------------------------------------------------------
// Box() - User Defined Constructor
Box::Box( double width, double length, double height ) :
m_volume( 0.0 ),
m_surfaceArea( 0.0 ) {

    if ( width <= 0 ) {
        m_width = 1.0;
    } else {
        m_width = width;
    }

    if ( length <= 0 ) {
        m_length = 1.0;
    } else {
        m_length = length;
    }

    if ( height <= 0 ) {
        m_height = 1.0;
    } else {
        m_height = height;
    }

    calculateVolume();
    calculateSurfaceArea();

} // Box

// -------------------------------------------------------------------------
// setWidth()
void Box::setWidth( double width ) {
    // First Check To See If Value Passed In Is Same Member Value
    if ( width == m_width ) {
        // Nothing To Do
        return;
    } else if ( width <= 0 ) {
        m_width = 1.0
    } else {
        m_width = width;
    }

    calculateVolume();
    calculateSurfaceArea();

} // setWidth

// -------------------------------------------------------------------------
// setLength()
void Box::setLength( double length ) {
    // First Check To See If Value Passed In Is Same Member Value
    if ( length == m_length ) {
        // Nothing To Do
        return;
    } else if ( length <= 0 ) {
        m_length = 1.0
    } else {
        m_length = length;
    }

    calculateVolume();
    calculateSurfaceArea();

} // setLength

// -------------------------------------------------------------------------
// setHeight()
void Box::setHeight( double height ) {
    // First Check To See If Value Passed In Is Same Member Value
    if ( height == m_height ) {
        // Nothing To Do
        return;
    } else if ( height <= 0 ) {
        m_height = 1.0
    } else {
        m_height = height;
    }

    calculateVolume();
    calculateSurfaceArea();

} // setHeight

// -------------------------------------------------------------------------
// getWidth()
double Box::getWidth() const {
    return m_width;
} // getWidth

// -------------------------------------------------------------------------
// getLength()
double Box::getLength() const {
    return m_length;
} // getLength

// -------------------------------------------------------------------------
// getHeight()
double Box::getHeight() const {
    return m_height;
} // getHeight;

// -------------------------------------------------------------------------
// getVolume()
double Box::getVolume() const {
    return m_volume;
} // getVolume

// -------------------------------------------------------------------------
// getSurfaceArea()
double Box::getSurfaceArea() const {
    return m_surfaceArea;
} // getSurfaceArea

// -------------------------------------------------------------------------
// calculateVolume()
void Box::calculateVolume() {
    m_volume = m_width * m_length * m_height;
} // calculateVolume

// -------------------------------------------------------------------------
// calculateSurfaceArea()
void Box::calculateSurfaceArea {
    m_dSurfaceArea = (m_width  * m_length * 2) + 
                     (m_width  * m_height * 2) +
                     (m_length * m_height * 2);
} // calculateSurfaceArea

With the design of this class the calculations for both the volume and surface area are private to this class only for all they do is an internal calculation that get saves into the classes member variable where there are public access methods available to retrieve them. 通过此类的设计,体积和表面积的计算仅对此类专有,因为它们所做的全部是内部计算,该计算保存到类成员变量中,在该成员变量中可以使用公共访问方法来检索它们。 Also each of the 3 dimensional setters does the same check as both constructors for values that are less than and equal to 0 and if so will default them to 1. 同样,3维设置器中的每一个都与两个构造器进行相同的检查,以得出小于和等于0的值,如果是,则将其默认设置为1。

If the value that is passed into any of the setter functions is the same that is already stored the function will do nothing and just return. 如果传递给任何setter函数的值与已存储的值相同,则该函数将不执行任何操作,仅返回。 If the value is greater than 0 and is not equal to what is already saved, it will overwrite the member variable and call both of the private calculate methods to update the volume and surface area. 如果该值大于0且不等于已保存的值,它将覆盖成员变量并调用两个私有计算方法以更新体积和表面积。

Now if you want to improve this for better performance then you can declare both calculate methods as inline, move them out of the cpp file and either add them into the header file after your class declaration and before the #endif or you can add an `#include "Box.inl" and just create another header file type with the same name as the class except with the inl extension and cut and paste these two functions in there. 现在,如果您想改善此性能以获得更好的性能,则可以将两个计算方法都声明为内联,将它们移出cpp文件,然后在类声明之后和#endif之前将它们添加到头文件中,或者可以添加` #include“ Box.inl”,只是创建另一个与该类同名的头文件类型,除了带有inl扩展名,然后在其中剪切和粘贴这两个函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM