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

时间:2015-10-24 00:57:38

标签: c++

我的程序应该计算一个盒子的表面积和体积。我将拥有以下函数:setHeight,setWidth,setLength,getVolume,getSurfaceArea。

编译程序时,我收到以下错误消息:

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()

根据我在此网站上的搜索,大多数答案似乎表明默认构造函数不会退出或无法正常工作。我不知道这是不是我的问题,但我根据教科书编写了我的默认构造函数的代码,所以我很难搞清楚我做错了什么。

我的代码中缺少的行只是我删除的描述和注释。

任何帮助将不胜感激!非常感谢你们。

这是我的.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();
 };

这是我的函数.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);
 }

这是我的主要.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;
 }

3 个答案:

答案 0 :(得分:6)

Box::getVolume被声明为不带参数,但在第21行中你用3个参数调用它:

box1.getVolume(h, w, l)

只需使用box1.getVolume()即可。同样适用于Box::getSurface()

此外,在所有成员函数定义前面使用Box::,例如void Box::setHeight(double h) {...},否则您最终会定义自由站立函数,并且您将收到链接器错误因为成员函数最终没有定义。

答案 1 :(得分:2)

vsoftco的回答大多是正确的,所以我已经投票给他,虽然我觉得在答案中添加更多信息以帮助解释它更好以及帮助清理其他几个问题会更好你在这里。

如果你看一下,你已经清楚地解释了这个问题。它提到函数int main()中的boxMain.cpp有问题。它进一步为您提供行号,并提及没有匹配功能&#34;对于&#34;电话&#34;并且在两个实例中都记录了调用以及可能的候选者,在这种情况下是没有参数的方法。

除此之外,还有一些其他提示可以帮助您避免进一步的挫折:

  1. 首选转发声明而不是头文件中的包含。在您的情况下,您在box.hpp中根本不需要#include <iostream>。原因是标题中的任何内容都会有效泄露到包含标题的任何文件中。这主要是为了帮助减少循环依赖性以及缩短编译时间。 Pimpl Idiom是与此咒语一起使用的示例模式。我不建议使用裸指针,而是坚持使用RAII类型,例如smart pointers或普通引用。

  2. 您要么不粘贴所有代码,要么include guard错误。您需要在标题中关闭#endif

  3. 您应该使用约定来命名成员变量以避免冲突并使您的大.cpp文件更易于阅读。这是一个偏好,而不是一个规则,但它有所帮助。类似于_heightmHeight_mHeight而不是height。小写的camel样式变量名称对于本地和参数是常见的。看起来你根本不需要h,w,l成员。

  4. 您应该使用assert进行错误处理,以便在发布版本期间对其进行优化。除非您打算向最终用户显示错误消息,否则这是粗略的。您也可以考虑使用std::cerr代替。

  5. .cpp中的heightwidthlength变量也是无关紧要的,不符合您的想法。

  6. 您应该在构造函数中使用初始化列表,而不是简单地分配给正文中的变量。还有一些特殊情况,但this可以帮助您入门。 例如:Box::Box() : height(1.0), width(1.0), length(1.0){}

  7. 使用Box::完全限定的cpp中唯一的方法是构造函数。您还需要使用所有方法。例如:double Box::getVolume()

  8. 你也没有在你的main函数中调用正确的方法(事实上你根本就没有调用方法。你基本上是在向前声明它们。)你应该使用一个对象来调用它方法。这就是为什么您没有在错误日志中看到有关丢失Box::的投诉

答案 2 :(得分:1)

您的头文件中有一个主要错误与您的类声明无关,但在预编译阶段与标头有关。你的头部防守不正确,因为你先在守卫前面有#include <iostream>;这应该是在后卫之后。您的#ifndef CLASS_NAME秒与您的#define CLASS_NAME不符,并且您在头文件底部缺少匹配的#endif。我将删除#include <iostream>,因为不需要它。我这样做的原因是因为如果用户输入的值小于或等于零,则将其设置为默认值1.因此无需打印此类的任何错误消息。

你的课程接近你所需要的。有一些事情可以帮助改善你的课程,也许这会有所帮助。

<强> 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

#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

通过这个类的设计,体积和表面区域的计算对于这个类来说是私有的,只是他们所做的只是一个内部计算,它将保存到类成员变量中,其中有可用的公共访问方法来检索它们。此外,每个三维设置器对两个值小于等于0的构造函数执行相同的检查,如果是,则将它们默认为1.

如果传递给任何setter函数的值与已存储的值相同,则该函数将不执行任何操作并返回。如果该值大于0且不等于已保存的值,则它将覆盖成员变量并调用两个私有计算方法以更新体积和表面积。

现在,如果您想提高性能以获得更好的性能,那么您可以将两个计算方法声明为内联,将它们移出cpp文件,并在类声明之后和#endif之前将它们添加到头文件中或者你可以添加一个`#include“Box.inl”,只需创建另一个与该类同名的头文件类型,除了带有inl扩展名,然后在这里剪切并粘贴这两个函数。