前向声明 另外一个命名空间中的类,有几种写法?

CandPointer 2011-03-26 06:48:04
怎么样才能 使用前向声明 另外一个命名空间中的类?



//file01.h
namespace A01{
class Aa {...}; //类Aa在这里定义
}

---------
//file02.h

namespace A01{
class Aa; //前向声明A01中的类Aa;
}
/*
*请问,这里的前向声明,这样写有什么问题?
*还有没有其它更合适的写法?
*为什么 class A01::Aa; 这样作为前向声明,是不行的?
*/

namespace B01{
class Bb {
...
A01::Aa * ptrAa; //使用类Aa的指针
...
};
}


...全文
2285 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
helloyangqi 2013-11-12
  • 打赏
  • 举报
回复
引用
qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。 结论:一个玩wow玩出优越感的程序员。
确实 喷了半天都不明白楼主的意思 如果可以包含头文件解决还要前置声明这玩意吗 我实验了不用typedef也可以 namespace sql { class ResultSet; } using sql::ResultSet;
wencan2012 2013-05-17
  • 打赏
  • 举报
回复
namespace boost { class thread; }; typedef boost::shared_ptr<boost::thread> thread_pt; 这是我的代码
  • 打赏
  • 举报
回复
qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。

结论:一个玩wow玩出优越感的程序员。
lgstudyvc 2011-08-12
  • 打赏
  • 举报
回复
问一下,把namespace用在类的外部 有什么好处?什么情况下需要这么用?
Sachow 2011-06-15
  • 打赏
  • 举报
回复
补充:


//File1.h
namespace A {
class A01 {...};
}

//File2.h
using A::A01;

//File2.cpp
#include "File1.h" // 注意包含顺序,含有前向声明对象实现的单元要包含在前面
#include "File2.h"
Sachow 2011-06-15
  • 打赏
  • 举报
回复
//File1.h
namespace A {
class A01 {...};
}

//File2.h
using A::A01;

//File2.cpp
#include "File1.h"

VS2005编译通过
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
复制乱了。。自己看着弄吧。
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
楼主,你namespace学的很差火候,没法给你讲,真的。

当你在不同的头文件里定义同一个namespace的时候,它们虽然同名,但谁也不认识谁,只有当你讲它们都包含到一个文件里的时候,它们才知道原来都是一家人.

我只能说这一点,其他的看实际情况,我在你基础上写点代码,你自己理解去吧.

我做这个东西的时候,是按顺序来的,如下:

head1.h

#if !defined HEAD1_H
#define HEAD1_H

namespace A
{
class T
{
public:
T(int);
int n;
};
}
head1.cpp
[code=C/C++]#include "head1.h"

using namespace A; //完全释放出来head1.h里的namespace A

T::T(int _n):n(_n)
{
}


#endif[/code]

head2.h
#if !defined HEAD2_H
#define HEAD2_H

namespace A
{
class T;

int useT(const T &);
}

#endif


head2.cpp
#include "head2.h"
#include "head1.h"
using namespace A; //最初只想完全释放出head2.h里的namespace A,后来需要T类定义,所以这一下两个都释放出来了

int /*看到我犯贱的全局作用域么? */::useT(const T &obj)
{
/*
我要返回T里的成员变量,所以必须见到T的类定义,所以马上包含进来head1.h
*/
return obj.n;
}


主函数

#include <iostream>
#include "head1.h" //为了用类T
#include "head2.h" //为了用函数userT
using namespace std;

int main()
{
A::T a(2); //我只用到了头文件head1
cout<<A::useT(a)<<endl; //我只用头文件head2,至于head1.h会前置声明类T,head1.cpp会包含head2.h我就不关心了,都已经一步一步依赖好了

return 0;
}


showjim 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 candpointer 的回复:]
目前,试过的,可行的,不包含 file01.h
用 前置声明,
好像就只有 下面的写法
[/Quote]
有一种写法不就可以了,可能是C++标准就这样定义的吧(不太清楚)。
showjim 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 candpointer 的回复:]
引用 7 楼 pengzhixi 的回复:

因为你具体的定义在另外一个头文件。所以肯定要将那个头文件包含进来。否则无法链接


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?
[/Quote]
如果仅仅是指针,不涉及成员调用,确实可以前置,而且是可靠的。
showjim 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 candpointer 的回复:]
namespace A01{
class Aa; //前向声明A01中的类Aa;
}

namespace B01{
class Bb {
...
A01::Aa * ptrAa; //使用类Aa的指针
...
};
}
[/Quote]
以前试过,这样写也是不可靠的,只声明不会有问题。如果使用这个类的话还与连接顺序有关。
最好把定义与实现分开,使用#include包含定义
gergerman 2011-03-30
  • 打赏
  • 举报
回复
不明真相围观当中
cxyOOOO 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 qq120848369 的回复:]

看23楼.
[/Quote]

平心静气更适合讨论问题,我大致理解你的意思了。

这里给出我对lz疑问的理解(不一定是正确的,需要考证)
1, namespace是定义不是声明。
若使用 class A01::Aa;而A01是个命名空间,则需要A01的确切定义,而不是声明。

2, 即使在scope中能找到命名空间A01的定义,但是A01的成员列表里没有定义Aa(命名空间的成员列表是可以扩展的),仍会导致编译出错。

解决的办法可以这样:
在.cpp文件中
先#include "file01.h"
后#include "file02.h"
则"file02.h"中的class A01::Aa可用。(file02.h依赖file01.h中对A01的定义)
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 candpointer 的回复:]

引用 21 楼 qq120848369 的回复:

C/C++ code
namespace A01 //我是美女A01,我在家乐福一层(file1.h)
{
class Aa
{
};
}




//------------------------------------------------------
//#include "file1.h" 我正在……
[/Quote]

拜托你,搞明白,为什么要在某些情况下,尽量在头文件使用前置声明,而不是完整地包含其他头文件,再来说吧。

你可以去看一下effective c++,只是个建议,你是高手,伤不起。

qq120848369 2011-03-30
  • 打赏
  • 举报
回复
好的,我不会,你等其他人来回答,我围观。
CandPointer 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 qq120848369 的回复:]

C/C++ code
namespace A01 //我是美女A01,我在家乐福一层(file1.h)
{
class Aa
{
};
}




//------------------------------------------------------
//#include "file1.h" 我正在向下俯瞰

namespace B01 //……
[/Quote]


..............至于这个 21楼

你是先删除我1楼原本的 前置声明。
然后,再玩弄文字游戏。

拜托你,搞明白,为什么要在某些情况下,尽量在头文件使用前置声明,而不是完整地包含其他头文件,再来说吧。



//file02.h

namespace A01{
class Aa; //前向声明A01中的类Aa;
}
CandPointer 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 qq120848369 的回复:]

以后看样不能嘲讽楼主了,仇恨太高,让楼主已经忘记了来干什么的。
[/Quote]


你根本没有明白,不包含头文件,为什么只是使用到 前置声明(Forward declaration)。

至于说我前面有什么仇恨的吗?我想,那是你自己吧。我只是在16楼纠正了你在14楼关于“犯贱的全局”,

至于你那19楼跛脚的东西,你看清楚我1楼的内容再说吧。

google: forward declaration of a class in another namespace
google: forward declaration with namespace

http://www.eggheadcafe.com/software/aspnet/35709155/forward-declaration-of-class-from-another-namespace.aspx
http://bytes.com/topic/c/answers/506268-forward-declaration-class-namespace
http://www.velocityreviews.com/forums/t457441-forward-declaration-of-a-class-in-another-namespace.html


不多解释。我想,你是典型的 90后中的某部分人吧?
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
以后看样不能嘲讽楼主了,仇恨太高,让楼主已经忘记了来干什么的。
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 cxyoooo 的回复:]

ls扯的有点远

lz问的是这个问题
这个可以
namespace A01{
class Aa; //前向声明A01中的类Aa;
}

/*
*请问,这里的前向声明,这样写有什么问题?
*还有没有其它更合适的写法?
*为什么 class A01::Aa; 这样作为前向声明,是不行的?
*/

这个不行
class A01::Aa;
[/Quote]

看23楼.
qq120848369 2011-03-30
  • 打赏
  • 举报
回复
楼主的问题其实不是namespace不会用,是类的定义和成员函数的声明这里稍微有点混乱。

函数声明T func(T *); 只要欺骗func,我有一个类型的确是T即可,所以这时候用前置声明即可,无论T到底有没有,到底在哪里。

class T;
T func(T *);

函数定义呢,假设我要访问T里的一个数据成员,前置声明够不够,肯定不够。

class T;
T func(T *obj)
{cout<<obj.a<<endl;}

很明显,obj.a是什么,你并没有告诉编译器。

所以这里前置声明是没用的,需要T类的完整定义,而不是T类的成员函数定义

正确做法如下:
class T
{
public : int a;
};

T func(T *obj)
{cout<<obj.a<<endl;}

这样就可以了。

至于

class T
{
public : int a;
};
放在哪里,当然是说放在一个单独的头文件里T.h,上面的代码可以写成:

#include "T.h"
T func(T *obj)
{cout<<obj.a<<endl;}

当然,如果你的T func(T *)头文件里做了一些特殊的函数声明,比如dllexport,或者extern "C",则必须
#include "T.h"
#include "func.h"
T func(T *obj)
{cout<<obj.a<<endl;}

func.h里比如是这样的:
class T;
extern "C" T func(T *);

加载更多回复(17)

64,636

社区成员

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

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