#include <iostream>
using namespace std;
int GenerateID()
{
static int nextID = 0;
return nextID++;
}
void PrintInformation(Employee EmployeeName)
{
cout << EmployeeName << "'s ID is: " << EmployeeName.ID << endl;
cout << EmployeeName << "'s age is: " << EmployeeName.age << endl;
cout << EmployeeName << "'s wage is: " << EmployeeName.wage << endl;
}
int main()
{
struct Employee
{
int ID;
int age;
float wage;
};
Employee Dominic;
Employee Jeffrey;
Dominic.ID = GenerateID();
Dominic.age = 22;
Dominic.wage = 7.10;
Jeffrey.ID = GenerateID();
Jeffrey.age = 28;
Dominic.wage = 7.10;
PrintInformation(Dominic);
PrintInformation(Jeffrey);
return 0;
}
/*
C:\CBProjects\Practise\main.cpp|11|error: variable or field 'PrintInformation' declared void|
C:\CBProjects\Practise\main.cpp|11|error: 'Employee' was not declared in this scope|
C:\CBProjects\Practise\main.cpp||In function 'int main()':|
C:\CBProjects\Practise\main.cpp|39|error: 'PrintInformation' was not declared in this scope|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 0 seconds) ===|
*/
上面的pastebin链接显示了我使用的代码和构建报告。在此报告之后,我尝试转发声明结构而不包含成员,然后出现“不完整类型”错误。
解决方案是什么?
编辑:我正在使用c ++ 11
编辑2:如果我尝试转发声明结构,包括成员:
,会发生什么答案 0 :(得分:5)
有两种解决方案:将Employee
设为非本地类/结构或使PrintInformation
成为模板。对于第一个解决方案,只需在 Employee
之前移动PrintInformation
。第二个解决方案是:
template< typename Employee >
void PrintInformation(const Employee& EmployeeName)
{
cout << " EmployeeName's ID is: " << EmployeeName.ID << endl;
cout << " EmployeeName's age is: " << EmployeeName.age << endl;
cout << " EmployeeName's wage is: " << EmployeeName.wage << endl;
}
请注意,在任何情况下,您都不希望Employee
的副本仅打印某些信息,因此如上所示,使PrintInformation
的参数成为常量参考。
答案 1 :(得分:2)
错误中的第一条信息是行号。
C:\CBProjects\Practise\main.cpp|11|error: variable or field 'PrintInformation' declared void|
第11行。让我们看一下第11行。
void PrintInformation(Employee EmployeeName)
这一切看起来都有效,但什么是员工?直到第21行我们才发现它。您的函数PrintInformation想要使用PrintInformation的内部管道,因此函数实际上需要知道struct / class的完整定义。
除此之外,您还通过在函数内定义Employee,将Employee定义为私有类型main
。您实际声明的内容是main::Employee
。
一些解决方案:
在与PrintInformation相同的范围内声明“Employee”,即在包含等之后的文件顶部的全局范围。
或者使“PrintInformation”成为Employee的成员函数。
struct Employee
{
void PrintInformation()
{
std::cout << " Employee's ID is: " << ID << '\n';
std::cout << " Employee's age is: " << age << '\n';
std::cout << " Employee's wage is: " << wage << '\n';
}
...
};
...
Dominic.PrintInformation();
或实施运营商&lt;&lt; (可能是你现在所处的位置)。
我还想指出风格的一个方面,让你在下游遇到一些严重的问题:你对变量和类型使用相同的UpperCamelCase,但与类型不一致。如果你自学成员变量的前缀并在早期保持一致的情况下,它会对你有所帮助:
struct Employee // UpperCamel for types.
{
int m_id;
int m_age;
float m_wage;
};
现在可以很容易地分离局部变量和类型以及成员变量。当您开始了解成员函数时,这将变得特别有用。
struct Employee // UpperCamel for types.
{
int m_id;
std::string m_name;
int m_age;
float m_wage;
Employee(const std::string& name, int age, float wage)
: m_id(nextID++)
, m_name(name)
, m_age(age)
, m_wage(wage)
{}
...
};
答案 2 :(得分:0)
您应先在struct Employee
中使用PrintInformation()
之前声明PrintInformation
,或使PrintInformation()
成为模板(如@DanielFrey所做的那样)。
将struct
修复为关注,因为您无法直接打印<<
数据,除非您为结构重载void PrintInformation(Employee EmployeeName)
{
cout << " EmployeeName's ID is: " << EmployeeName.ID << endl;
cout << " EmployeeName's age is: " << EmployeeName.age << endl;
cout << " EmployeeName's wage is: " << EmployeeName.wage << endl;
}
(请查看here如何进行操作这一点)。
{{1}}