我的程序应该计算一个盒子的表面积和体积。我将拥有以下函数: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;
}
答案 0 :(得分:6)
Box::getVolume
被声明为不带参数,但在第21行中你用3个参数调用它:
box1.getVolume(h, w, l)
只需使用box1.getVolume()
即可。同样适用于Box::getSurface()
。
此外,在所有成员函数定义前面使用Box::
,例如void Box::setHeight(double h) {...}
,否则您最终会定义自由站立函数,并且您将收到链接器错误因为成员函数最终没有定义。
答案 1 :(得分:2)
如果你看一下,你已经清楚地解释了这个问题。它提到函数int main()
中的boxMain.cpp有问题。它进一步为您提供行号,并提及没有匹配功能&#34;对于&#34;电话&#34;并且在两个实例中都记录了调用以及可能的候选者,在这种情况下是没有参数的方法。
首选转发声明而不是头文件中的包含。在您的情况下,您在box.hpp中根本不需要#include <iostream>
。原因是标题中的任何内容都会有效泄露到包含标题的任何文件中。这主要是为了帮助减少循环依赖性以及缩短编译时间。 Pimpl Idiom是与此咒语一起使用的示例模式。我不建议使用裸指针,而是坚持使用RAII类型,例如smart pointers或普通引用。
您要么不粘贴所有代码,要么include guard错误。您需要在标题中关闭#endif
。
您应该使用约定来命名成员变量以避免冲突并使您的大.cpp文件更易于阅读。这是一个偏好,而不是一个规则,但它有所帮助。类似于_height
,mHeight
,_mHeight
而不是height
。小写的camel样式变量名称对于本地和参数是常见的。看起来你根本不需要h,w,l
成员。
您应该使用assert
进行错误处理,以便在发布版本期间对其进行优化。除非您打算向最终用户显示错误消息,否则这是粗略的。您也可以考虑使用std::cerr代替。
.cpp中的height
,width
,length
变量也是无关紧要的,不符合您的想法。
您应该在构造函数中使用初始化列表,而不是简单地分配给正文中的变量。还有一些特殊情况,但this可以帮助您入门。
例如:Box::Box() : height(1.0), width(1.0), length(1.0){}
使用Box::
完全限定的cpp中唯一的方法是构造函数。您还需要使用所有方法。例如:double Box::getVolume()
你也没有在你的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扩展名,然后在这里剪切并粘贴这两个函数。