I am running into below error - when I just provide the definition of class first and then declare it later. My understanding was as long as we do that as I have done numerous times for function definition, compiler gets it but seems my understanding is flawed can someone help me understand what is missing part in understanding of how to declare class.
error C2027: use of undefined type 'generic_iterator'
note: see declaration of 'generic_iterator
Does not work - error shown above
#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;
};
Works : When entire class is declared first
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;
};
When you declare a summary of something before using it, this is called a forward declaration.
When making a forward declaration to a function, the compiler has everything it needs in order to parse code which invokes that function: the name of the function, the type returned, the number of arguments, and the type of each argument.
But when making a forward declaration to a class, the compiler only knows that this particular symbol (generic_iterator
in your case) is a class. Subsequently, the only thing you can do with it before it has been fully defined is to declare a pointer to it. (And people with more knowledge of C++ than me might know one or two additional arcane uses.) You cannot invoke any of its members, because the compiler does not yet know its structure. Your code is trying to invoke the constructor of your forward-referenced class, but the compiler does not know of any such constructor yet.
I do not know of any easy way to resolve this problem. Others might have some better solutions, but the way I tend to resolve this problem is by moving all of the code that needs to access members of a forwardly declared class from the .h
file to the .cpp
file. So, in your case, in the .h
file I would simply write iterator begin();
and then in the .cpp
file I would write generic_iterator darray::begin() {return iterator(ptrarray); }
.
This would compile, because at that moment the complete class definition of generic_iterator
is known.
The compiler needs to know the definition of the class generic_iterator
whan it is parsing these function definitions
iterator begin() {return iterator(ptrarray); }
iterator end() { return iterator(ptrarray + size); }
Otherwise it is unable to say whether this code is correct that is whether class generic_iterator
has a constructor that can be called with one argument.
Take into account that it would be correct to declare a constant subscript operator along with the non-constant operator. For example
int& operator [](int i);
const int& operator [](int i) const;
or
int& operator [](int i);
int operator [](int i) const;
Also try to use the qualifier const
with member functions that do not change the object itself like for example empty
or max_size
or maybe print
bool empty() const;
void print() const;
size_t max_size()const;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With