我尝试编写程序来管理Store。它有一些用户和商品和订单。 这是我的User.h,Good.h文件:
User.h:
#ifndef _USER
#define _USER
#include "Store.h"
#include "Good.h"
namespace question1
{
class User
{
const Store store;
public:
User(Store &s) : store ( s )
{
}
};
class AdminUser:User
{
};
class DeliveryUser:User
{
};
class OrderUser:User
{
void registerOrder(Order &o);
};
class ReceptionUser:User
{
void importGood(Good &g);
void increaseGood(Good &g);
};
}
#endif
和Good.h:
#ifndef _GOOD
#define _GOOD
#include <string>
#include <vector>
#include "User.h"
namespace question1
{
class Date
{
public:
Date ();
Date ( int mn, int day, int yr); // constructor
void display(); // function to display date
int GetMonth();
void SetMonth(int mn);
~Date();
private:
int month, day, year;
int DaysSoFar();
};
enum Ordertype{Newly_registered, Check, Answered};
class Order
{
int num;
std::string customerName;
Date registered, Check;
Ordertype type;
std::vector<int> codelist, numlist;
public:
Order();
Order(Order& o);
};
class ImportDate
{
Date importDate;
User importer;
int num;
};
class ExportDate
{
Date exportDate;
User exporter;
int num;
Order ex;
};
class Good
{
std::string name;
int code;
Date in;
int innum, AvailableNum;
User importer;
std::vector<ImportDate> importHistory;
std::vector<ExportDate> exportHistory;
public:
Good();
Good(Good &g);
};
int max (int a, int b)
{
if (a>b) return(a) ; else return (b);
}
int min (int a, int b)
{
if (a>b) return(b); else return (a);
}
}
#endif
但是当编译这两个代码时,我在用户文件中出错了
“语法错误:标识符'订单',第28行
“语法错误:标识符'好',第33行
“语法错误:标识符'好',第34行
在函数参数列表中。 我使用visual studio 2010.并打开空项目。
任何人都可以帮助我吗?
答案 0 :(得分:2)
您有循环参考。简而言之,你最终会得到这样的结论:
class Good
{
User * fn() {} // What is a User?
};
class User
{
Good * fn() {}
};
C ++的行为与C#不同,并且自上而下读取文件,因此当遇到对User的第一次引用时,它还不知道它是什么。即使你切换了类的顺序,问题也会返回。
您可能应该将它们放在同一个文件中并使用类型转发:
class User;
class Good
{
User * fn() {} // Ah, User is some class. Go on.
};
class User
{
Good * fn() {}
};
或(正如Agentlien建议的那样):
class User;
class Good
{
User fn();
};
class User
{
Good fn();
};
User Good::fn() { return User(); }
Good User::fn() { return Good(); }
答案 1 :(得分:0)
这里的问题是,第一次编译器到达类或函数的定义时,需要声明它使用的所有类型。所以,例如,拥有:
void importGood(Good &g);
User.h 中的表示必须在此函数声明之前声明Good
。最好使用前向声明来完成,只需将其写为以下行:
class Good;
这需要在使用此类型的任何函数的声明之前放置,否则编译器不知道它是类型的名称,并且您得到编译器错误。
通常情况下,只需#include
定义此类型的文件即可。但是,这种方法有两个缺点:
价格贵很多。即使您使用包含保护,系统仍然必须先读取并标记文件,然后才能确定您对其内容不感兴趣。
每当你有一个循环依赖,例如在你的情况下,它将无济于事。编译器将简单地开始编译,例如 User.cpp 。然后它将包含 User.h ,几乎会立即遇到#include "Good.h"
。从那时起,它将进入 Good.h 。在那里,你(再次)尝试#include User.h
,由于包含警卫,这将在很大程度上被忽略。因此,只要在 Good.h 中使用User
,编译器仍然没有看到它的声明。
前向声明通过在第一次使用之前将类的声明直接放在其使用的文件中来解决这个问题。
通常,您应该更喜欢在头文件中使用前向声明,并避免包含其他头。只要有可能。
您实际需要直接在标头中包含某些内容的唯一时间是在您创建在该标头中声明的类型的实例时(例如,将其作为不是指针或引用的成员变量)或者当您在标题中使用该类的成员(例如函数或成员变量)时。这就是为什么将函数定义放在cpp文件而不是标题中总是一个好主意的原因之一。