在同一namespace里定义了,却报错说未声明的奇怪问题

麻辣丝瓜 2010-04-18 06:14:34
先是定义了一个Buffer类。如下


#include "TransLib.h"

namespace TransLib
{
template <typename Key> class BufferPool;

/* 缓冲区 */
class Buffer
{
//内部定义省略
private:
template <typename Key> friend class BufferPool;
Buffer(const Buffer& buffer);
Buffer& operator=(const Buffer& buffer);
};


可是在同一namespace里的其他类却无法识别这个类。必须在使用之前声明 class Buffer;才不会报错。如下:

namespace TransLib
{
class Buffer; //不晓得为什么,一定要声明,可能有错

class Socket {
public:
#ifdef POSIX
typedef int Target;
#endif
enum ReturnType{
SUCCESS,
NOTEXIST,
TIMEOUT,
SENDING
};
virtual Socket* instance() = 0;
virtual ReturnType init() = 0;
virtual const Target& connect(const char* pHostName, const char* pService) = 0;
virtual ReturnType sendTo(const Target& target, Buffer* pBuffer, const size_t nLength) = 0;
virtual ReturnType receiveFrom(const Target& target, Buffer* pBuffer, size_t* pLength) = 0;
virtual ReturnType close(const Target& target) = 0;
protected:
Socket* _pInstance;
virtual ~Socket() = 0;
};
}


尤其是另外的一个类里面:

namespace TransLib
{
class Buffer; //不晓得为什么,一定要声明,可能有错
这里错误:forward declaration of ‘struct TransLib::Buffer’

template <typename Key>
class BufferPool
{
};

template<typename Key>
bool BufferPool<Key>::removeBuffer(const Key& key)
{
这里错误:expected ‘;’ before ‘iter’
std::map<Key, Buffer*>::iterator iter = _pBufferMap->find(key);
这里错误:‘iter’ was not declared in this scope
if(iter == _pBufferMap->end())
return false;
else
{
delete iter->second; _pBufferMap->erase(iter);
}
}

}


BufferPool类.h文件中,如果不声明class Buffer;会报错说Buffer未声明,但是声明了却错了。
而且凡是用到map::iterator的地方都有问题。
我用的是Eclipse在linux下编译的。
希望各位高手给出解答,谢谢了
...全文
1684 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
麻辣丝瓜 2010-05-18
  • 打赏
  • 举报
回复
唉,算了,结账吧,都差点忘了。
everbeing 2010-05-05
  • 打赏
  • 举报
回复
#ifndef _TRANSLIB_BUFFERPOOL_H_
#define _TRANSLIB_BUFFERPOOL_H_

#include "TransLib.h"
#include "Buffer.h"
#include <map>

namespace TransLib
在这个BufferPool头文件里加上一句 using namespace TransLib;
虽然你BufferPool里的BufferPool类和Buffer.h里的Buffer类同属一个命名空间TransLib,但在BufferPool进行包含用到Buffer类的时候也须加上命名空间进行定位.
麻辣丝瓜 2010-05-05
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 arong1234 的回复:]
buffer.h里是什么?
[/Quote]

以下是Buffer.h里的所有内容

#ifndef _TRANSLIB_BUFFER_H_
#define _TRANSLIB_BUFFER_H_

#include "TransLib.h"

namespace TransLib
{
template <typename Key> class BufferPool;

/* 缓冲区 */
class Buffer
{
public:
/*
* 将初始地址为pData长度为nSize的内存复制到缓冲区中
* 返回:成功返回true,长度过长溢出,则失败返回false
*/
bool addData(const void* pData, const size_t nSize);
/*
* 将初始地址为pData长度为nSize的内存复制到缓冲区中,
* 若缓冲区大小不足自动增加大小,一定成功(只要内存够)
*/
void addDataSafely(const void* pData, const size_t nSize);
/*
* 删除缓冲区中末端的指定长度的数据,
* 成功返回true,否则长度过长溢出返回false
*/
bool removeData(const size_t nLengthToDelete);

void* getDataStart() const;
void* getDataEnd() const;
void* getLastDataStart(size_t nLength) const;
const size_t getBufferSize() const;
const size_t getDataSize() const;
const size_t resize(const size_t nNewSize);
/* 清空缓冲区 */
void clear();
protected:
/* nBufferSize:缓冲区最大尺寸 */
Buffer(const size_t nBufferSize = MSG_MAX_SIZE);
virtual ~Buffer();

const static size_t _BLANKSIZE = 20; //预申请的内存大小
void* _pBuffer; //缓冲区地址
void* _pDataStart; //缓冲区中有效数据的开始处
void* _pDataEnd; //缓冲区中有效数据的末尾处,新数据的起点处
size_t _nBufferSize; //缓冲区最大长度
private:
//Buffer类只能由BufferPool类实例化
template <typename Key> friend class BufferPool;
Buffer(const Buffer& buffer);
Buffer& operator=(const Buffer& buffer);
};

inline Buffer::~Buffer()
{
free(_pBuffer);
}

inline void* Buffer::getDataStart() const
{
return _pDataStart;
}

inline void* Buffer::getDataEnd() const
{
return _pDataEnd;
}

inline void* Buffer::getLastDataStart(size_t nLength) const
{
return (char*)_pDataEnd - nLength;
}

inline const size_t Buffer::getBufferSize() const
{
return _nBufferSize;
}

inline const size_t Buffer::getDataSize() const
{
return (char*)_pDataEnd - (char*)_pDataStart;
}

inline void Buffer::clear()
{
_pDataEnd = _pDataStart = _pBuffer;
}
}

#endif /* _TRANSLIB_BUFFER_H_ */
arong1234 2010-04-23
  • 打赏
  • 举报
回复
buffer.h里是什么?
麻辣丝瓜 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 angel_su 的回复:]
class Buffer
...
template <typename Key> friend class BufferPool;

不大会懂模板,但是上面看起来很奇怪,个人理解BufferPool这时是不是应该得实例化
friend class BufferPool<xxx>

若不要,那Buffer还有未定的东西,是不是也要写成模板形式?
template <typename ……
[/Quote]

我的这个BufferPool不需要实例化的,因为BufferPool的模板类型指的是取Buffer的键的类型,与Buffer类无关的。我那样声明是为了让所有实例的BufferPool都是Buffer的友元。
麻辣丝瓜 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 arong1234 的回复:]
不可能存在所谓的“定义不进去”的问题,肯定是你有些问题没弄明白。
只要有超前引用的问题,首先你必须把超前引用解决掉

然后你把所有的错误都帖下来,估计你还有一些拼写错误之类的问题

引用 7 楼 zha_1525515 的回复:
自己顶,困扰顶,郁闷顶
[/Quote]

如果把BufferPool上面声明class Buffer;的代码注释掉。就会有如下错误:
描述 资源 路径 位置 类型
‘Buffer’ has not been declared Socket.h /TransLib 第 41 行 C/C++ Problem
‘Buffer’ has not been declared Socket.h /TransLib 第 44 行 C/C++ Problem
‘Buffer’ has not been declared UDPSocket.h /TransLib 第 61 行 C/C++ Problem
‘Buffer’ has not been declared UDPSocket.h /TransLib 第 75 行 C/C++ Problem
‘Buffer’ was not declared in this scope BufferPool.h /TransLib 第 50 行 C/C++ Problem
‘Buffer’ was not declared in this scope BufferPool.h /TransLib 第 88 行 C/C++ Problem
‘Buffer’ was not declared in this scope BufferPool.h /TransLib 第 98 行 C/C++ Problem
‘Buffer’ was not declared in this scope BufferPool.h /TransLib 第 112 行 C/C++ Problem
‘Buffer’ was not declared in this scope BufferPool.h /TransLib 第 118 行 C/C++ Problem
‘iter’ was not declared in this scope BufferPool.h /TransLib 第 89 行 C/C++ Problem
‘iter’ was not declared in this scope BufferPool.h /TransLib 第 99 行 C/C++ Problem
‘iter’ was not declared in this scope BufferPool.h /TransLib 第 119 行 C/C++ Problem
expected ‘;’ before ‘*’ token BufferPool.h /TransLib 第 33 行 C/C++ Problem
expected ‘;’ before ‘*’ token Socket.h /TransLib 第 54 行 C/C++ Problem
expected ‘)’ before ‘*’ token Socket.h /TransLib 第 51 行 C/C++ Problem
expected constructor, destructor, or type conversion before ‘*’ token BufferPool.h /TransLib 第 58 行 C/C++ Problem
expected initializer before ‘iter’ BufferPool.h /TransLib 第 88 行 C/C++ Problem
expected initializer before ‘iter’ BufferPool.h /TransLib 第 98 行 C/C++ Problem
expected initializer before ‘iter’ BufferPool.h /TransLib 第 118 行 C/C++ Problem
ISO C++ forbids declaration of ‘Buffer’ with no type BufferPool.h /TransLib 第 33 行 C/C++ Problem
ISO C++ forbids declaration of ‘Buffer’ with no type Socket.h /TransLib 第 54 行 C/C++ Problem
request for member ‘begin’ in ‘((TransLib::BufferPool<Key>*)this)->TransLib::BufferPool<Key>::_pBufferMap->’, which is of non-class type ‘int’ BufferPool.h /TransLib 第 119 行 C/C++ Problem
request for member ‘end’ in ‘((const TransLib::BufferPool<Key>*)this)->TransLib::BufferPool<Key>::_pBufferMap->’, which is of non-class type ‘int’ BufferPool.h /TransLib 第 89 行 C/C++ Problem
request for member ‘end’ in ‘((TransLib::BufferPool<Key>*)this)->TransLib::BufferPool<Key>::_pBufferMap->’, which is of non-class type ‘int’ BufferPool.h /TransLib 第 99 行 C/C++ Problem
request for member ‘end’ in ‘((TransLib::BufferPool<Key>*)this)->TransLib::BufferPool<Key>::_pBufferMap->’, which is of non-class type ‘int’ BufferPool.h /TransLib 第 119 行 C/C++ Problem
request for member ‘erase’ in ‘((TransLib::BufferPool<Key>*)this)->TransLib::BufferPool<Key>::_pBufferMap->’, which is of non-class type ‘int’ BufferPool.h /TransLib 第 104 行 C/C++ Problem
template argument 2 is invalid BufferPool.h /TransLib 第 50 行 C/C++ Problem
template argument 2 is invalid BufferPool.h /TransLib 第 88 行 C/C++ Problem
template argument 2 is invalid BufferPool.h /TransLib 第 98 行 C/C++ Problem
template argument 2 is invalid BufferPool.h /TransLib 第 112 行 C/C++ Problem
template argument 2 is invalid BufferPool.h /TransLib 第 118 行 C/C++ Problem
template argument 4 is invalid BufferPool.h /TransLib 第 50 行 C/C++ Problem
template argument 4 is invalid BufferPool.h /TransLib 第 88 行 C/C++ Problem
template argument 4 is invalid BufferPool.h /TransLib 第 98 行 C/C++ Problem
template argument 4 is invalid BufferPool.h /TransLib 第 112 行 C/C++ Problem
template argument 4 is invalid BufferPool.h /TransLib 第 118 行 C/C++ Problem


BufferPool的代码是这样的:

#ifndef _TRANSLIB_BUFFERPOOL_H_
#define _TRANSLIB_BUFFERPOOL_H_

#include "TransLib.h"
#include "Buffer.h"
#include <map>

namespace TransLib
{
//class Buffer; //不晓得为什么,一定要声明,可能有错

/* 缓冲区池,一个Key对应一个缓冲区 */
template <typename Key>
class BufferPool
{
public:
/* 创建指定 */
BufferPool(const size_t nMaxSize);

/*
* 获取Buffer,若不存在则创建,大小为nBufferSize
* 若指定缓冲区不在池中,且未指定大小,不能创建,则返回0(即不指定大小,可只返回以存在的缓冲区)
* 若指定缓冲区不在池中,指定大小要创建,但是缓冲池满,则返回0
*/
Buffer* getBuffer(const Key& key, size_t nBufferSize = 0);

/*
* 判断指定的缓冲区是否在缓冲区池中,
* 存在返回true,否则返回false
*/
bool isBufferExist(const Key& key) const;

/*
* 删除指定的Buffer,成功返回true,
* 若指定Buffer不存在,返回false,
*/
bool removeBuffer(const Key& key);

virtual ~BufferPool();

protected:
std::map<Key, Buffer*>* _pBufferMap; /* 由Key指定Buffer */
size_t _nMaxSize; /* 缓冲区池最大容量 */

BufferPool(const BufferPool& bufferPool); //只声明
BufferPool& operator=(const BufferPool& bufferPool); //只声明
};

template<typename Key>
Buffer* BufferPool<Key>::getBuffer(const Key& key,
size_t nBufferSize/* = 0*/)
{
std::map<Key, Buffer*>::iterator iter = _pBufferMap->find(key);
if(iter == _pBufferMap->end()) //指定缓冲区不存在
{
if(nBufferSize == 0) //未指定缓冲区大小,无法创建
return 0;
else
{
if(_pBufferMap->size() == _nMaxSize) //已满
return 0;
else //未满,且不存在,则创建
{
Buffer* pNewBuffer = new Buffer(nBufferSize);
_pBufferMap->insert(
std::pair<Key, Buffer*>(key, pNewBuffer));
return pNewBuffer;
}
}
}
else //指定缓冲区存在
{
return iter->second;
}
}

template<typename Key>
bool BufferPool<Key>::isBufferExist(const Key& key) const
{
std::map<Key, Buffer*>::iterator iter = _pBufferMap->find(key);
if(iter == _pBufferMap->end())
return false;
else
return true;
}

template<typename Key>
bool BufferPool<Key>::removeBuffer(const Key& key)
{
std::map<Key, Buffer*>::iterator iter = _pBufferMap->find(key);
if(iter == _pBufferMap->end())
return false;
else
{
delete iter->second; //删除Buffer
_pBufferMap->erase(iter);
}
}

template<typename Key>
BufferPool<Key>::BufferPool(const size_t nMaxSize)
:_nMaxSize(nMaxSize)
{
_pBufferMap = new std::map<Key, Buffer*>();
}

template<typename Key>
BufferPool<Key>::~BufferPool()
{
std::map<Key, Buffer*>::iterator iter;
for(iter = _pBufferMap->begin(); iter != _pBufferMap->end(); iter++)
delete iter->second;
}
}
#endif /* _TRANSLIB_BUFFERPOOL_H_ */
angel_su 2010-04-20
  • 打赏
  • 举报
回复
class Buffer
...
template <typename Key> friend class BufferPool;

不大会懂模板,但是上面看起来很奇怪,个人理解BufferPool这时是不是应该得实例化
friend class BufferPool<xxx>

若不要,那Buffer还有未定的东西,是不是也要写成模板形式?
template <typename Key>
class Buffer
...
friend class BufferPool<Key>;
ForestDB 2010-04-20
  • 打赏
  • 举报
回复
帮顶。
麻辣丝瓜 2010-04-19
  • 打赏
  • 举报
回复
自己顶,困扰顶,郁闷顶
arong1234 2010-04-19
  • 打赏
  • 举报
回复
超前引用问题不是说你代码本身有问题,看一个类的定义毫无意义
[Quote=引用 6 楼 zha_1525515 的回复:]
引用 5 楼 arong1234 的回复:
看看http://www.vckbase.com/bbs/prime/viewprime.asp?id=431


谢谢,那篇文章我刚刚看了一下。可是我觉得我这个应该不是超前引用这类的问题。Buffer和BufferPool确实需要超前引用。但是我的同一命名空间下,还有Socket,UDPSocket这几个类,后来我试了一下,只要在这几个类的任何……
[/Quote]
arong1234 2010-04-19
  • 打赏
  • 举报
回复
不可能存在所谓的“定义不进去”的问题,肯定是你有些问题没弄明白。
只要有超前引用的问题,首先你必须把超前引用解决掉

然后你把所有的错误都帖下来,估计你还有一些拼写错误之类的问题
[Quote=引用 7 楼 zha_1525515 的回复:]
自己顶,困扰顶,郁闷顶
[/Quote]
麻辣丝瓜 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 arong1234 的回复:]
看看http://www.vckbase.com/bbs/prime/viewprime.asp?id=431
[/Quote]

谢谢,那篇文章我刚刚看了一下。可是我觉得我这个应该不是超前引用这类的问题。Buffer和BufferPool确实需要超前引用。但是我的同一命名空间下,还有Socket,UDPSocket这几个类,后来我试了一下,只要在这几个类的任何一个的定义之前声明class Buffer,所有的类就都认识了,如果不声明,就所有的类都不认识它。所以我怀疑可能Buffer没有成功的定义到namespace TransLib里面去。

namespace TransLib
{
template <typename Key> class BufferPool;

/* 缓冲区 */
class Buffer
{
public:
/*
* 将初始地址为pData长度为nSize的内存复制到缓冲区中
* 返回:成功返回true,长度过长溢出,则失败返回false
*/
bool addData(const void* pData, const size_t nSize);
/*
* 将初始地址为pData长度为nSize的内存复制到缓冲区中,
* 若缓冲区大小不足自动增加大小,一定成功(只要内存够)
*/
void addDataSafely(const void* pData, const size_t nSize);
/*
* 删除缓冲区中末端的指定长度的数据,
* 成功返回true,否则长度过长溢出返回false
*/
bool removeData(const size_t nLengthToDelete);

void* getDataStart() const;
void* getDataEnd() const;
const size_t getBufferSize() const;
const size_t getDataSize() const;
const size_t resize(const size_t nNewSize);
/* 清空缓冲区 */
void clear();
virtual ~Buffer();
protected:
/* nBufferSize:缓冲区最大尺寸 */
Buffer(const size_t nBufferSize = MSG_MAX_SIZE);

const static size_t _BLANKSIZE = 20; //预申请的内存大小
void* _pBuffer; //缓冲区地址
void* _pDataStart; //缓冲区中有效数据的开始处
void* _pDataEnd; //缓冲区中有效数据的末尾处,新数据的起点处
size_t _nBufferSize; //缓冲区最大长度
private:
//Buffer类只能由BufferPool类实例化
template <typename Key> friend class BufferPool;
Buffer(const Buffer& buffer);
Buffer& operator=(const Buffer& buffer);
};
}

Buffer类的定义是这样的,实在看不出有哪些不妥的。

除此之外,还有
这里错误:expected ‘;’ before ‘iter’
std::map<Key, Buffer*>::iterator iter = _pBufferMap->find(key);
这里错误:‘iter’ was not declared in this scope
if(iter == _pBufferMap->end()){……}
这样的问题,
麻辣丝瓜 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cattycat 的回复:]
你class Buffer没在namespace中啊。
map的问题,#include <map> using namespace std;
[/Quote]

Buffer是在namespace TransLib中定义的吧,那段代码下面有个"}"为复制掉了。
为的map都是std::map这样用的,而且就算用usina namespace std;也没有用。这个问题困扰我几天了,郁闷死了
麻辣丝瓜 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 arong1234 的回复:]
C++要求必须先定义后使用,而不是仅仅定义了就可以的。也就是说,如果你定义的这个类虽然在同一个namespace里,但是用的地方在定义之前,也不行
[/Quote]

这个是总的头文件
/*
* TransLib.h
*
* Created on: 2010-4-17
* Author: Peter_ZHA
* for:项目总头文件
*/

#ifndef _TRANSLIB_TRANSLIB_H_
#define _TRANSLIB_TRANSLIB_H_

#ifndef POSIX
#define POSIX
#endif /* POSIX */


#include <stdlib.h>
#include <string.h>
#include <map>

#include "MsgFormat.h"

#include "Buffer.h"
#include "BufferPool.h"

#include "Socket.h"
#include "UDPSocket.h"

extern const size_t MSG_MAX_SIZE;

#endif /* _TRANSLIB_TRANSLIB_H_ */

其余的.h都是包含这个头文件的。其中 BufferPool 要使用Buffer,所以Buffer的头文件为放在前面。而且为在BufferPool.h中BufferPool的定义前面还声明了class Buffer的。可是却报错forward declaration of ‘struct TransLib::Buffer’。还有一个就是Buffer中要声明BufferPool的友元,假设在Buffer类前面不声明BufferPool编译器也不报错。
cattycat 2010-04-18
  • 打赏
  • 举报
回复
你class Buffer没在namespace中啊。
map的问题,#include <map> using namespace std;
arong1234 2010-04-18
  • 打赏
  • 举报
回复
C++要求必须先定义后使用,而不是仅仅定义了就可以的。也就是说,如果你定义的这个类虽然在同一个namespace里,但是用的地方在定义之前,也不行

65,194

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧