我一直致力于硬件商店应用程序,其中有一个HardwareRecordclass存储有关商店中每个对象的信息(例如:螺母,螺栓,螺钉等)。
信息存储在" .dat"文件,但现在这并不重要。
这是我对这堂课的宣言:
// Definition of HardwareRecord class
#ifndef __Initialize_Hardware_Store_File__HardwareRecord__
#define __Initialize_Hardware_Store_File__HardwareRecord__
#include <iostream>
class HardwareRecord
{
public:
HardwareRecord(const int& account=0,const std::string& name="",const std::string& description="",const double& price=0.0); //constructor
HardwareRecord operator=(HardwareRecord&);
//'set' and 'get' functions
void setAccountNumber(int);
int getAccountNumber() const;
void setName(std::string);
std::string getName() const;
void setPrice(double);
double getPrice() const;
void setDescription(std::string);
std::string getDescription() const;
void wipeRecord(); //set everything to blank
private:
int myAccountNumber;
std::string myName;
std::string myDescription;
double myPrice;
};
#endif /* defined(__Initialize_Hardware_Store_File__HardwareRecord__) */
这是我的班级定义:
// Implementation of HardwareRecord class definition
#include <iostream>
#include "HardwareRecord.h"
using namespace std;
HardwareRecord HardwareRecord::operator=(HardwareRecord & aRecord)
{
this->myAccountNumber=aRecord.myAccountNumber;
this->myName=aRecord.myName;
this->myDescription=aRecord.myDescription;
this->myPrice=aRecord.myPrice;
return *this; //allow for cascaded overloading
}
HardwareRecord::HardwareRecord(const int& account,const string& name,const string&
description,const double& price)
{
setAccountNumber(account);
setName(name);
setPrice(price);
setDescription(description);
}
void HardwareRecord::wipeRecord()
{
setAccountNumber(0);
setName("");
setPrice(0);
setDescription("");
}
void HardwareRecord::setAccountNumber(int num)
{
if (num < 0)
{
throw invalid_argument("The account number is not in the valid range (greater or equal to 0)");
}
else
{
myAccountNumber=num;
}
}
int HardwareRecord::getAccountNumber() const
{
return myAccountNumber;
}
void HardwareRecord::setName(string name)
{
myName=name;
}
string HardwareRecord::getName() const
{
return myName;
}
void HardwareRecord::setPrice(double price)
{
if (price < 0)
{
throw invalid_argument("The price can not be less than zero");
}
else
{
myPrice=price;
}
}
double HardwareRecord::getPrice() const
{
return myPrice;
}
void HardwareRecord::setDescription(string description)
{
this->myDescription=description;
}
string HardwareRecord::getDescription() const
{
return myDescription;
}
所描述的类应该在以下main.cpp文件中使用:
// Application that models a store's record of inventory
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <sstream>
#include "HardwareRecord.h" //HardwareRecord definition
using namespace std;
//enumeration of choices
enum Choices {WIPE_RECORDS,UPDATE,LIST,PRINT,DELETE,NEW,END,LAST};
std::ostream& operator<<(std::ostream& op,const Choices& choices)
{
//print the string corresponding to the value of enum type Choices
string output="";
switch (choices)
{
case WIPE_RECORDS:
output = "wipe records";
break;
case UPDATE:
output = "update records";
break;
case LIST:
output = "list records";
break;
case PRINT:
output = "print records";
break;
case DELETE:
output = "delete records";
break;
case NEW:
output = "add new record";
break;
case END:
output = "terminate application";
break;
case LAST:
output = "an option used to iterate over the values in the Choice enumeration";
break;
default:
cerr << "Error. invalid value is read";
exit(EXIT_FAILURE);
break;
}
op << output; //print output
return op;
}
//prototype of helper functions
int enterChoice();
void wipeRecords(fstream&);
void updateRecord(fstream&);
void listRecords(fstream&);
void createTextFile(fstream&);
void deleteRecord(fstream&);
void newRecord(fstream&);
int main()
{
//open file for reading and writinbg
fstream outRecord ("HardwareRecord.dat",ios::in|ios::out|ios::binary);
//exit program if fstream cannot open file
if (!outRecord)
{
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
}
int choice; //user's choice
//enable user to specify action
while ((choice=enterChoice()) !=END)
{
switch (choice)
{
case WIPE_RECORDS: //wipe all records clean
wipeRecords(outRecord);
break;
case UPDATE: //update a record
updateRecord(outRecord);
break;
case LIST: //list all current records
listRecords(outRecord);
break;
case PRINT: //print a record
createTextFile(outRecord);
break;
case DELETE: //delete a record
deleteRecord(outRecord);
break;
case NEW: //add a new record (if space allows)
newRecord(outRecord);
break;
default: //display error if user does not select valid choice
cerr << "Incorrect choice" << endl;
}
outRecord.clear();
}
return 0;
}
//enable user to input menu choice
int enterChoice()
{
//display avaliable options
cout << "\nEnter your choice:\n"<< endl;
Choices aChoice;
for (int c=WIPE_RECORDS; c < LAST; c++)
{
aChoice= (Choices) c;
cout << c << " - " << aChoice << endl;
}
cout << "\n?: ";
int menuChoice;
cin >> menuChoice;
return menuChoice;
}
void wipeRecords(fstream& theFile)
{
HardwareRecord temp;
for (int i=0; i < 100;i++)
{
//convert record from binary and assign to temp
//make temp "wipe itself"
}
}
是的,我意识到许多函数都是由prototype定义的,但实际上并没有声明。这将在之后不久描述的这个问题得到修复之后完成。请从以下文件中注意以下代码:
void wipeRecords(fstream& theFile)
{
HardwareRecord temp; //Here's where the error occurs: No Matching constructor!
for (int i=0; i < 100;i++)
{
//convert record from binary and assign to temp
//make temp "wipe itself"
}
}
每当我尝试在我的Mac上编译这个项目(我使用xCode)时,我会对注释的行产生以下错误。错误是&#34;没有匹配的构造函数用于初始化&#39; HardwareRecord&#39;&#34;。但是,我为HardwareRecord对象的构造函数提供了默认值,因此行
HardwareRecord temp;
应该没有任何问题进行初始化。
发生了什么事?我该如何解决这个问题?
答案 0 :(得分:1)
我认为这是问题所在。在构造函数中,您使用的是std::string&
,但是从未在代码中包含<string>
!
除了一些其他错误外,使用G ++进行编译可以得到:
prog.cpp:46:57:错误:'string'没有命名类型
这可能会使您的默认构造函数无效。
答案 1 :(得分:-3)
您正在尝试使用默认构造函数。
HardwareRecord temp;
但是你已经声明了一个带参数的构造函数,以及一个赋值运算符。声明带参数的构造函数的行为意味着编译器不会为您生成默认构造函数。因此,如果你想要一个,你必须自己声明一个或使用你创建的构造函数。
修改
我的上述答案不正确,因为OP为所有指定的参数提供了默认值。
在我指定的情况下,编译器将声明如下:
error: no matching function for call to ‘Foo::Foo()’
但是如果指定了默认值,它将编译。
小测试:
- foo.h
class Foo
{
private:
int _i;
public:
Foo( int i );
};
- foo.cpp
#include "foo.h"
Foo::Foo( int i )
: _i( i )
{
}
int main()
{
Foo foo;
return 0;
}
答案 2 :(得分:-3)
HardwareRecord类应具有默认构造函数,例如:
class HardwareRecord { public: HardwareRecord() : myAccountNumber(0), myName(""), myDescription(""), myPrice(0.0f) {} ... };
您当前使用默认参数值的构造函数似乎不被视为默认构造函数&#39;。