2015-10-06 125 views
-1

我有下面的类(它基本上是std :: vector的包装器),其中一个函数返回AInteger类型的变量(它基本上是一个int类型的包装器)。现在AInteger类在整个类中被多次使用,但编译器开始抱怨一个非常特定的位置。当我删除“getSize()”函数时,一切都编译得很好。前置声明被忽略?

有相互包含,所以我需要前进宣言的一切工作。

其中一个问题是,AList类是一个模板,所以不可能将定义移动到.cpp文件(通常可以解决问题)。

我在做什么错?

这里的类:

#ifndef ALIST_H 
#define ALIST_H 

#include <vector> 

#include "AInteger.h" 

class AInteger; 

template<typename VALUE> 
class AList { 
public: 
    AList() { 
    } 

    AList(const std::vector<VALUE> list) { 
     value = list; 
    } 

    ~AList() { 
    } 

    operator const std::vector<VALUE>() const { 
     return value; 
    } 

    std::vector<VALUE> toStdVector() const { 
     return value; 
    } 

    VALUE operator [](const AInteger index) const { 
     return value.at(index); 
    } 

    void add(const VALUE value) { 
     this->value.push_back(value); 
    } 

    VALUE get(const AInteger index) const { 
     return value[index]; 
    } 

    AInteger getSize() const { // ERROR OCCURS HERE 
     return value.size(); 
    } 

    void remove(const AInteger index) { 
     value.erase(index); 
    } 

private: 
    std::vector<VALUE> value; 
}; 

#endif 

输出:

1>------ Build started: Project: ALibrary, Configuration: Debug Win32 ------ 
1> ASocket.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> AInteger.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> AHttpRequest.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> ABoolean.cpp 
1>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
1> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
1> Generating Code... 
1> Compiling... 
1> AString.cpp 
1> Generating Code... 
2>------ Build started: Project: BitHoarder, Configuration: Debug Win32 ------ 
2> SystemHandler.cpp 
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
2> Main.cpp 
2>d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(43): error C2027: use of undefined type 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(8): note: see declaration of 'AInteger' 
2> d:\programs\programming\visual studio projects\c++\alibrary\alibrary\alist.h(53): note: see reference to class template instantiation 'AList<VALUE>' being compiled 
2> Generating Code... 
========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ========== 

如果需要更多的代码,只是问,我会提供。

谢谢!

编辑: 下面是这里面的“AInteger.h”

#ifndef AINTEGER_H 
#define AINTEGER_H 

#include "AList.h" 

template<typename VALUE> 
class AList; 

class AInteger { 
public: 
    AInteger(); 
    AInteger(const int); 
    ~AInteger(); 

    operator const int() const; 

    int toInt() const; 

    AInteger operator=(const AInteger &); 
    AInteger & operator++(); 
    AInteger & operator--(); 

    AList<AInteger>splitByNumber(const AInteger &); 

private: 
    int value; 
}; 

#endif 

使事情更加混乱,下面的类,它不完全一样的事情不会产生错误的代码:

#ifndef ADICTIONARY_H 
#define ADICTIONARY_H 

#include <map> 

#include "AInteger.h" 

class AInteger; 

template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY>> 
class ADictionary { 
public: 
    ADictionary() { 
    } 

    ADictionary(const std::map<KEY, VALUE, COMPARE> dictionary) { 
     value = dictionary; 
    } 

    ~ADictionary() { 
    } 

    operator const std::map<KEY, VALUE, COMPARE>() const { 
     return value; 
    } 

    std::map<KEY, VALUE, COMPARE> toStdMap() const { 
     return value; 
    } 

    VALUE operator [](const KEY key) const { 
     return value.at(key); 
    } 

    void add(const KEY key, const VALUE value) { 
     this->value.insert(std::make_pair(key, value)); 
    } 

    VALUE get(const KEY key) const { 
     return value[key]; 
    } 

    AInteger getSize() const { // No error here 
     return value.size(); 
    } 

    void remove(const KEY key) { 
     value.erase(value.find(key)); 
    } 

private: 
    std::map<KEY, VALUE, COMPARE> value; 
}; 

#endif 
+2

是不是AInteger在 “AInteger.h” 声明?如果是这样,为什么包括后需要声明? – vmg

+0

@vmg有相互包含,所以我需要转发声明,否则我会得到错误。 – Qub1

+1

转发声明不会神奇地消除相互包含。 – juanchopanza

回答

4

getSize()的执行必须创建一个AInteger的实例。这仅在已知AInteger的完整定义时才可能。您不能创建只有前向声明的类型的实例。

这正是编译器告诉你的:error C2027: use of undefined type 'AInteger'。它不会忽略前向声明,但告诉你,这是不够的。

至于#include "AInteger.h",你不显示其内容,但可能的问题是:

  • 巴吉包括在头文件中后卫使编译器跳过定义。
  • 头文件定义了一个具有类似名称的不同类型。
  • AInteger的定义在名称空间内。
+0

好的,但为什么编译器会忽略#include呢?它不应该有定义吗?谢谢您的帮助! – Qub1

+0

@ Qub1:AInteger.h是否定义了类型? –

+0

那么它包含了AInteger类及其函数的声明,包括构造函数。所以我很困惑为什么编译器会忽略所有这些。 – Qub1

2

问题出在Christian Hackl的答案中回答得很好,通常我会把它放在那里,但我无法解释OP如何在评论中正确解决这个问题。

首先修订AInteger.h

#ifndef AINTEGER_H 
#define AINTEGER_H 

template<typename VALUE> 
class AList; 

class AInteger { 
public: 
    AInteger(); 
    AInteger(const int); 
    ~AInteger(); 

    //operator const int() const; 

    int toInt() const; 

    AInteger operator=(const AInteger &); 
    AInteger & operator++(); 
    AInteger & operator--(); 

    std::unique_ptr<AList<AInteger>> splitByNumber(const AInteger &); 
    void splitByNumber(const AInteger &, 
         AList<AInteger> &); 

private: 
    int value; 
}; 

#endif 

的包括AList.h已经一去不复返了。 AList的前向声明仍然提供了两种不同的splitByNumber方法。选一个。第一个创建并返回a pointer protected by a smart pointer。第二种方法和我的个人偏好,引用由调用者创建的AList。

这件事既不知道AList的内部工作,因为他们关心的只是A)它存在和b)他们可以得到一个地址。

在我探索这两者的同时忍受着我,因为我认为它们都是教育性的。

除了删除前向声明AInteger之外,Alist.h保持不变。

两个splitByNumber候选人坐在AInteger的执行文件,它可以安全地包括AInteger.h和AList.h,从而在同一时间既具有完整的知识,可以做所有的神奇的东西AIntegersALists可以做。

std::unique_ptr<AList<AInteger>> AInteger::splitByNumber(const AInteger & integer) 
{ 
    std::unique_ptr<AList<AInteger>> listp(new AList<AInteger>()); 

    // do stuff with listp 
    return listp; 
} 

void AInteger::splitByNumber(const AInteger & integer, 
          AList<AInteger> & list) 
{ 
    // do stuff with list 
} 

使用指针版本:

std::unique_ptr<AList<AInteger>> alistp = aitest1.splitByNumber(aitest2); 
alistp->add(somenumber); 

使用参考版本:

AList<AInteger> alist; // first create an empty AList 
aitest1.splitByNumber(aitest2, alist); // pass it into the function 
alist.add(somenumber); // use the AList