2013-04-17 30 views
0

我试着编写程序来管理Store。它有一些用户和商品以及订单。 这是我User.h,Good.h文件:找不到C++函数参数标识

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.并打开空项目。

有人可以帮助我吗?

+3

你在'#include'语句中有循环引用。第一个标题包含另一个包含第一个标题等等。 –

+0

@Captain我认为这是#ifndef和#define声明的目的。但我仍然会给出一个镜头 – tay10r

+1

@TaylorFlores标题防护程序可防止多次编译头文件的内容。它不会阻止循环'#include'语句。 –

回答

2

您有一个循环参考。总之,你最终是这样的:

class Good 
{ 
    User * fn() {} // What is a User? 
}; 

class User 
{ 
    Good * fn() {} 
}; 

C++不表现得像C#和读取文件自上而下的,所以当它遇到的第一个提到的用户,它仍然不知道,是什么它是。即使您切换类的顺序,问题也会返回。

你或许应该把它们放在同一个文件,并使用转发类型:

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

因为您在类定义中定义了函数'Good :: fn',所以它也不会编译。这样做,返回类型不能是不完整的类型,所以前向声明它并不能解决问题。您还需要将函数定义移至“User”的定义之后。 – Agentlien

+0

@Agentlien你说得对,我想'User *'和'Good *',而是写了'User'和'Good'。感谢您的验证。修改代码,他们现在都会编译。 – Spook

+0

好多了。 :) – Agentlien

0

这里的问题是,在第一时间编译达到一个类或函数的定义,它使用的所有类型都需要声明。所以,举例来说,有:

void importGood(Good &g); 

User.h,意味着Good有这个函数声明之前声明。这是通过使用前瞻性声明,这是简单地写成一行,如做得最好:

class Good; 

这需要使用这种类型的任何函数的声明之前放,否则编译器没有按不知道它是一个类型的名称,并且你得到编译器错误。

通常情况下,它也可以简单地用#include这个类型定义的文件。但是,这种方法有两个缺点:

  1. 这是一个更昂贵的。即使你使用了包括守卫,系统仍然必须读取并标记文件,然后才能确定你对其内容不感兴趣。

  2. 无论何时你有循环依赖,例如你的情况,它都无济于事。编译器将开始编译,例如,User.cpp。然后它将包括User.h,并且几乎会立即遇到#include "Good.h"。从此,它将输入Good.h。在那里,你(再次)试图#include User.h,由于包括后卫,这将被大量忽略。因此,只要在User中使用Good.h,编译器仍然没有看到它的声明。

正向声明解决了这个问题,在第一次使用之前,直接将声明放在使用它的文件中。

通常,您应该更喜欢在头文件中使用前向声明,并避免包含其他头文件。只要有可能。

实际需要直接从头文件中包含某些东西的唯一时间是当您创建在该头文件中声明的类型的实例时(例如,将其作为不是指针或引用的成员变量)或者当您在标题中使用该类的成员(例如函数或成员变量)时。这是为什么把函数定义放在cpp文件而不是头文件中总是一个好主意的原因。