错误 C2027:使用未定义类型 - 如何声明类

Posted

技术标签:

【中文标题】错误 C2027:使用未定义类型 - 如何声明类【英文标题】:error C2027: use of undefined type - how to declare class 【发布时间】:2015-11-27 21:29:05 【问题描述】:

我遇到了以下错误 - 当我先提供类的定义然后再声明它时。我的理解是,只要我们这样做,因为我已经为函数定义做了很多次,编译器会理解它,但似乎我的理解有缺陷,有人可以帮助我理解在理解如何声明类方面缺少的部分。

error C2027: use of undefined type 'generic_iterator'
note: see declaration of 'generic_iterator  

不起作用 - 如上所示的错误

#include <iostream>
class generic_iterator;
class darray

public:
    typedef generic_iterator iterator;
    darray();
    darray(int size);
    ~darray();
    int& at(int index);
    int& operator [](int i);
    int* data(void);
    bool empty();
    void fill(int val);
    void print();
    size_t max_size();
    iterator begin() return iterator(ptrarray); 
    iterator end()  return iterator(ptrarray + size); 

private:
    int *ptrarray;
    int num_elements;
    int size;
;

class generic_iterator

public:
    generic_iterator(int *ptr);
    ~generic_iterator();
    generic_iterator& operator++();     // pre-increment
    generic_iterator operator++(int);    // post-increment
private:
    int *iptr;
;

有效:首先声明整个类时

class generic_iterator

public:
    generic_iterator(int *ptr);
    ~generic_iterator();
    generic_iterator& operator++();     // pre-increment
    generic_iterator operator++(int);    // post-increment
private:
    int *iptr;
;

class darray

public:
    typedef generic_iterator iterator;
    darray();
    darray(int size);
    ~darray();
    int& at(int index);
    int& operator [](int i);
    int* data(void);
    bool empty();
    void fill(int val);
    void print();
    size_t max_size();
    iterator begin() return iterator(ptrarray); 
    iterator end()  return iterator(ptrarray + size); 

private:
    int *ptrarray;
    int num_elements;
    int size;
;

【问题讨论】:

【参考方案1】:

当您在使用之前声明某事物的摘要时,这称为前向声明

在对函数进行前向声明时,编译器拥有解析调用该函数的代码所需的一切:函数的名称、返回的类型、参数的数量以及每个参数的类型。

但是当对一个类进行前向声明时,编译器只知道这个特定的符号(在你的例子中是generic_iterator)是一个类。随后,在它被完全定义之前,你唯一能做的就是声明一个指向它的指针。 (而且比我更了解 C++ 的人可能知道一两个额外的神秘用途。)您不能调用它的任何成员,因为编译器还不知道它的结构。您的代码正在尝试调用前向引用类的构造函数,但编译器还不知道任何此类构造函数。

我不知道有什么简单的方法可以解决这个问题。其他人可能有一些更好的解决方案,但我倾向于解决这个问题的方法是将所有需要访问前向声明类的成员的代码从.h 文件移动到.cpp 文件。所以,在你的情况下,在.h 文件中我会简单地写iterator begin();,然后在.cpp 文件中我会写generic_iterator darray::begin() return iterator(ptrarray);

这会编译,因为那时generic_iterator 的完整类定义是已知的。

【讨论】:

感谢您的回答和纠正我的行话 - 所以工作方式是解决错误的唯一方法 - 或者在这种情况下还有其他方法来声明前向声明? @ifelse 我修改了我的答案。 啊哈!!!我现在明白了,通常我在 .cpp 中声明,这次我将它声明为 inline 并且我遇到了错误。我想现在我更好了..非常感谢!【参考方案2】:

编译器在解析这些函数定义时需要知道类generic_iterator的定义

iterator begin() return iterator(ptrarray); 
iterator end()  return iterator(ptrarray + size); 

否则无法说这段代码是否正确,即类generic_iterator是否有一个可以用一个参数调用的构造函数。

考虑到将常量下标运算符与非常量运算符一起声明是正确的。例如

int& operator [](int i);
const int& operator [](int i) const;

int& operator [](int i);
int operator [](int i) const;

还可以尝试将限定符 const 与不改变对象本身的成员函数一起使用,例如 emptymax_sizeprint

bool empty() const;
void print() const;
size_t max_size()const;

【讨论】:

感谢关于类的其他函数的指针 - 所以我展示的 sn-p of 的工作方式是声明类的唯一方法,即在使用之前先完全定义它它在其他类 - 或者我需要记住其他一些形式的前向声明? @ifelse 可以在迭代器的类定义之后在类定义之外定义这些函数(它们只会在类定义中声明)。

以上是关于错误 C2027:使用未定义类型 - 如何声明类的主要内容,如果未能解决你的问题,请参考以下文章

带有前向声明的循环包含和继承导致 C2504 基类未定义

基类未定义,但包含其标头

错误 C2504:'BASECLASS':基类未定义

ES6 代理类,访问私有属性(无法从类未声明的对象中读取私有成员#hidden)

Phonegap 推送通知类未找到错误

DoubleLinkedList 删除错误