关于友元的类的,一个编译错误,求解
这个是主文件
- C/C++ code
#include <iostream>#include <vector>#include "Triangulate_iterator.h"using namespace std;static int arr[13] = {1,1,2,3,5,8,13,21,34,55,89,144,233};class Triangulate {public: typedef Triangulate_iterator iterator; friend class Triangulate_iterator; //这里已经声明Triangulate_iterator为友元类 Triangulate(); Triangulate(int length , int beg_pos); Triangulate(int length); Triangulate(const Triangulate&); Triangulate_iterator begin() { return Triangulate_iterator(_beg_pos); } Triangulate_iterator end() { return Triangulate_iterator(_beg_pos + _length); } int length() const { return _length; } int beg_pos() const { return _beg_pos; } int length() { return _length; } int beg_pos() { return _beg_pos; } bool next(int &x) const; void next_reset() const; static bool is_elem( int ); static void gen_elements( int length ); static void gen_elems_to_value( int value ); static void display( int length, int beg_pos, ostream &os = cout ); static vector<int> _elem;private: string _name; int _length; int _beg_pos; mutable int _next; static const int _max_elems = 1024;};Triangulate::Triangulate() : _length(1),_beg_pos(1),_next(0),_name("Triangulate") {}Triangulate::Triangulate(int l, int b) : _name("Triangulate") { _length = l > 0 ? l : 1; _beg_pos = b > 0 ? b : 1; _next = _beg_pos-1;}Triangulate::Triangulate(int l) : _name("Triangulate") { _length = l > 0 ? l : 1; _beg_pos = 1; _next = _beg_pos - 1;}Triangulate::Triangulate(const Triangulate &rhs) { _length = rhs._length; _beg_pos = rhs._beg_pos; _next = rhs._next; _name = rhs._name;}bool Triangulate::next(int &elem) const { if(_next >= _length) return false; elem = _elem[_next]; _next++; return true;}void Triangulate::next_reset() const { _next = _beg_pos - 1;}vector<int> Triangulate::_elem(arr,arr+13);int sum( const Triangulate &trian ) { if ( !trian.length()) return 0; int sum = 0; int val = 0; trian.next_reset(); while ( trian.next( val )) sum += val; return sum;}bool Triangulate::is_elem( int value ) { if ( !_elem.size() || _elem[_elem.size()-1] < value) gen_elems_to_value(value); vector<int>::iterator found; vector<int>::iterator last = _elem.end(); found = find(_elem.begin(), last, value); return found != last;}void Triangulate::gen_elems_to_value( int value ) { int ix = _elem.size(); if ( !ix ) { _elem.push_back(1); ix = 1; } if ( ix == 1) { _elem.push_back(1); ix = 2; } while ( _elem[ix-1] < value && ix < _max_elems) { _elem.push_back(_elem[ix-2] + _elem[ix-1]); ix++; } if( ix == _max_elems ) cerr << " value too large " << value << " -- exceeds max size of " << _max_elems << endl;}void Triangulate::gen_elements( int length ) { if ( length <= 0 || length > _max_elems ) return; int ix = _elem.size(); if ( length == 1 && ix < length ) { _elem.push_back(1); ix++; } if ( length == 2 && ix < length ) { if( ix == 0) { _elem.push_back(1); ++ix; } _elem.push_back(1); ++ix; } for (; ix < length; ix++ ) { _elem.push_back(_elem[ix-2] + _elem[ix-1]); }}Triangulate_iterator.h文件
- C/C++ code
#ifndef TRIANGULATE_ITERATOR_H_INCLUDED#define TRIANGULATE_ITERATOR_H_INCLUDEDclass Triangulate;class Triangulate_iterator {public: class Triangulate; Triangulate_iterator(int index) : _index(index-1) {} bool operator== ( const Triangulate_iterator& ) const; bool operator!= ( const Triangulate_iterator& ) const; int Triangulate_iterator::operator* (const Triangulate_iterator &rhs); Triangulate_iterator& operator++ (); Triangulate_iterator operator++ ( int );private: void check_integrity() const; int _index;};inline bool Triangulate_iterator::operator == ( const Triangulate_iterator& rhs ) const { return this->_index == rhs._index;}inline bool Triangulate_iterator::operator != ( const Triangulate_iterator& rhs ) const { return (! (*this == rhs ));}int Triangulate_iterator::operator* (const Triangulate_iterator &rhs) { rhs.check_integrity(); return Triangulate::_elem[_index]; //这里编译出现错误}Triangulate_iterator& Triangulate_iterator::operator++ () { _index++; check_integrity(); return *this;}Triangulate_iterator Triangulate_iterator::operator++ ( int ) { Triangulate_iterator tem = *this; _index++; check_integrity(); return tem;}void Triangulate_iterator::check_integrity() const { }#endif // TRIANGULATE_ITERATOR_H_INCLUDED
主要是这里
int Triangulate_iterator::operator* (const Triangulate_iterator &rhs) {
rhs.check_integrity();
return Triangulate::_elem[_index]; //这里编译出现错误
}
错误提示是
D:\cpp\codblock\essentialch4\Triangulate_iterator.h|49|error: incomplete type `Triangulate' used in nested name specifier|
错误:不完全类型“Triangulate”用于嵌套名称说明符|
不懂这个错误是什么意思,要怎么改啊!
[解决办法]
你这个定义方法陷入了先有鸡还是先有蛋的问题。
你的Triangulate_iterator依赖于Triangulate //编译错误那里直接使用了本文件前面只声明,还未定义的类型。
而Triangulate又依赖于Triangulate_iterator //比如你在begin里直接返回Triangulate_iterator对象
记住一点:在使用某个类的成员,或者构造对象 前的文件中必须含有些类的完整定义 ! 只有个声明的情况下,只能使用指针(和引用?) 。 但是不能访问其成员!
iterator里面不能使用原始类型了,得使用原始对象“里面”的类型,比如这个可以使用vector<int> _elem传进去。
代码如下,使用cc -c Triangulate.c 编译通过。
- C/C++ code
#include <iostream>#include <vector>#include <algorithm> //使用find得包含这个头#include "Triangulate_iterator.h"using namespace std;static int arr[13] = {1,1,2,3,5,8,13,21,34,55,89,144,233};class Triangulate {public: typedef Triangulate_iterator iterator; friend class Triangulate_iterator; //这里已经声明Triangulate_iterator为友元类 Triangulate(); Triangulate(int length , int beg_pos); Triangulate(int length); Triangulate(const Triangulate&); Triangulate_iterator begin() { return Triangulate_iterator(_elem,_beg_pos); //这里改下 } Triangulate_iterator end() { return Triangulate_iterator(_elem , _beg_pos + _length); } int length() const { return _length; } int beg_pos() const { return _beg_pos; } int length() { return _length; } int beg_pos() { return _beg_pos; } bool next(int &x) const; void next_reset() const; static bool is_elem( int ); static void gen_elements( int length ); static void gen_elems_to_value( int value ); static void display( int length, int beg_pos, ostream &os = cout ); static vector<int> _elem;private: string _name; int _length; int _beg_pos; mutable int _next; static const int _max_elems = 1024;};Triangulate::Triangulate() : _length(1),_beg_pos(1),_next(0),_name("Triangulate") {}Triangulate::Triangulate(int l, int b) : _name("Triangulate") { _length = l > 0 ? l : 1; _beg_pos = b > 0 ? b : 1; _next = _beg_pos-1;}Triangulate::Triangulate(int l) : _name("Triangulate") { _length = l > 0 ? l : 1; _beg_pos = 1; _next = _beg_pos - 1;}Triangulate::Triangulate(const Triangulate &rhs) { _length = rhs._length; _beg_pos = rhs._beg_pos; _next = rhs._next; _name = rhs._name;}bool Triangulate::next(int &elem) const { if(_next >= _length) return false; elem = _elem[_next]; _next++; return true;}void Triangulate::next_reset() const { _next = _beg_pos - 1;}vector<int> Triangulate::_elem(arr,arr+13);int sum( const Triangulate &trian ) { if ( !trian.length()) return 0; int sum = 0; int val = 0; trian.next_reset(); while ( trian.next( val )) sum += val; return sum;}bool Triangulate::is_elem( int value ) { if ( !_elem.size() || _elem[_elem.size()-1] < value) gen_elems_to_value(value); vector<int>::iterator found; vector<int>::iterator last = _elem.end(); found = find(_elem.begin(), last, value); return found != last;}void Triangulate::gen_elems_to_value( int value ) { int ix = _elem.size(); if ( !ix ) { _elem.push_back(1); ix = 1; } if ( ix == 1) { _elem.push_back(1); ix = 2; } while ( _elem[ix-1] < value && ix < _max_elems) { _elem.push_back(_elem[ix-2] + _elem[ix-1]); ix++; } if( ix == _max_elems ) cerr << " value too large " << value << " -- exceeds max size of " << _max_elems << endl;}void Triangulate::gen_elements( int length ) { if ( length <= 0 || length > _max_elems ) return; int ix = _elem.size(); if ( length == 1 && ix < length ) { _elem.push_back(1); ix++; } if ( length == 2 && ix < length ) { if( ix == 0) { _elem.push_back(1); ++ix; } _elem.push_back(1); ++ix; } for (; ix < length; ix++ ) { _elem.push_back(_elem[ix-2] + _elem[ix-1]); }}
[解决办法]
return Triangulate::_elem[_index]; //这里编译出现错误
因为你前面只有class Triangulate
编译器只认识Triangulate 不认识_elem
把这东西丢进cpp里 在cpp的前面+ #include "Triangulate.h"
int Triangulate_iterator::operator* (const Triangulate_iterator &rhs) {
rhs.check_integrity();
return Triangulate::_elem[_index]; //这里编译出现错误
}