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

时间:2022-09-08 08:30:14
怎么样才能 使用前向声明 另外一个命名空间中的类?



//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的指针
...
};
}


37 个解决方案

#1


class  A01::Aa;

#2


或者using A01::Aa;

#3


引用 1 楼 pengzhixi 的回复:
class  A01::Aa;


你好,这个,这么写,好像都出错了
环境:
visual studio 2010 sp1 + Intel Parallel Studio 2011 (编译器 Intel C++ Compiler 12.0 )



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

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

class A01::Aa; //前置声明放在这里

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

//编译器报错
Error 1 error : name followed by "::" must be a class or namespace name




---------换一个地方写 class A01::Aa; 


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

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



namespace B01{

class A01::Aa; //把这个前置声明放在namespace B01里面

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

//编译器报错
Error 1 error : name followed by "::" must be a class or namespace name




#4


你肯定得include"file01.h"

#5


引用 2 楼 pengzhixi 的回复:
或者using A01::Aa;


试了一下,如果 没有包含 ( #include “file01.h”)

在 file02.h 里面
using A01::Aa; //这一行,直接error : name followed by "::" must be a class or namespace name   


目前,试过的,可行的,不包含 file01.h
用 前置声明,
好像就只有 下面的写法


namespace A01{
class Aa; //前向声明A01中的类Aa;
}

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


#6


引用 4 楼 pengzhixi 的回复:
你肯定得include"file01.h"


如果 要包含 include"file01.h"
那似乎,就没有使用 前置声明 的意义了吧?

#7


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

#8


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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

#9


无解,不知道哪错了.....

#10


本来就只有一种写法,有啥好折腾的。

#11


引用 5 楼 candpointer 的回复:
namespace A01{
class Aa; //前向声明A01中的类Aa;
}

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

以前试过,这样写也是不可靠的,只声明不会有问题。如果使用这个类的话还与连接顺序有关。
最好把定义与实现分开,使用#include包含定义

#12


引用 8 楼 candpointer 的回复:
引用 7 楼 pengzhixi 的回复:

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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

如果仅仅是指针,不涉及成员调用,确实可以前置,而且是可靠的。

#13


引用 5 楼 candpointer 的回复:
目前,试过的,可行的,不包含 file01.h
用 前置声明,
好像就只有 下面的写法

有一种写法不就可以了,可能是C++标准就这样定义的吧(不太清楚)。

#14


楼主,你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;
}


#15


复制乱了。。自己看着弄吧。

#16


引用 14 楼 qq120848369 的回复:
楼主,你namespace学的很差火候,没法给你讲,真的。

#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; }



看了下,这个,head1.h,不是前置声明类T,(forward declaration)...
看你head2.h,这个 算是 前置声明
namespace A
{
    class T;

    int useT(const T &);
}


我是要在 另外一个 namespace B的头文件里面 使用 namespace A中的class T
只是需要 指针或引用,所以想在head2.h里面,只用 前置声明,而没必要包含head1.h

但,看你这个........

另外,所谓的
int /*看到我犯贱的全局作用域么? */::useT


其实,你这个 useT,还是属于 namespace A。


至于你下面的这个,如果真只是需要类T的定义。
完全可以
using A::T;
而不是完整地using A。


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



我只想告诉你,你的【int /*看到我犯贱的全局作用域么? */::useT】 其实,是属于 namespace A的。



你的的确有点乱。

#17


引用 12 楼 sbwwkmyd 的回复:
引用 8 楼 candpointer 的回复:
引用 7 楼 pengzhixi 的回复:

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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

如果仅仅是……


好像,很多规范里面,都提到,避免太多的头文件依赖,要使用前置声明。
如果,只是用到 指针或者引用,是可以在头文件,安全地使用 前置声明的(forward declaration)
当然,如果用到了成员,那是需要完整地包含类的定义的头文件。

#18


引用 16 楼 candpointer 的回复:
[Quote=引用 14 楼 qq120848369 的回复:]

楼主,你namespace学的很差火候,没法给你讲,真的。

C/C++ code
#include <iostream> #include "head1.h" //为了用类T #include "head2.h" //为了用函数userT using namespace std; int main() { A::T ……


我知道说你差火候你就要喷我,所以我不在意,学习是你自己的,你完全可以当我放屁了.

#19


想学明白namespace,建议你去看看经常使用的各种头文件,例如:iostream,vector,map,set,你会发现,他们所有的模板定义与全局模板函数定义都是包括在_STD_BEGIN ,_STD_END里的。

为什么:

#include <iostream>
using namespace std;

vector<int> a; 提示找不到vector。

因为你没有包含<vector>,using std只是把iostream里的namespace std解开了。

如果你#include <vector>

那么iostream和vector在这里才知道原来彼此都在std里,大家一起暴露出来。

这就是我说的,std不过是个名字,在哪里用,谁也不知道,只有它们碰到一起的时候,才会累加起来。

#20


引用 17 楼 candpointer 的回复:
好像,很多规范里面,都提到,避免太多的头文件依赖,要使用前置声明。

我是初用C++,觉得#include用着挺方面,依赖层次多的话可以少写很多定义。
很想知道头文件有哪些缺陷?

#21


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




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

namespace B01 //我是帅哥B01,我在家乐福二层(file2.h). 我不认识A01,但我非常想知道她的身材好不好!
{ //那我必须先往下俯瞰一下,不仅要看看A01是谁,而且必须看看身材怎么样,这样才能意淫她!
class Bb
{
A01::Aa *ptrAa; //A01我见到了,身材也不错,是Aa的,我先意淫一下它的身材吧.
};
}

int main()
{
    return 0;
}

#22


ls扯的有点远

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

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

这个不行
class A01::Aa;

#23


楼主的问题其实不是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 *);

#24


引用 22 楼 cxyoooo 的回复:
ls扯的有点远

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

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

这个不行
class A01::Aa;


看23楼.

#25


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

#26


引用 25 楼 qq120848369 的回复:
以后看样不能嘲讽楼主了,仇恨太高,让楼主已经忘记了来干什么的。



你根本没有明白,不包含头文件,为什么只是使用到 前置声明(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后中的某部分人吧?

#27


引用 21 楼 qq120848369 的回复:
C/C++ code
namespace A01    //我是美女A01,我在家乐福一层(file1.h)
{
    class Aa 
    {
    }; 
}




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

namespace B01    //……



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

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

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



//file02.h

namespace A01{
class Aa; //前向声明A01中的类Aa;
}

#28


好的,我不会,你等其他人来回答,我围观。

#29


引用 27 楼 candpointer 的回复:
引用 21 楼 qq120848369 的回复:

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




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


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

你可以去看一下effective c++,只是个建议,你是高手,伤不起。 前向声明 另外一个命名空间中的类,有几种写法?

#30


引用 24 楼 qq120848369 的回复:
看23楼.


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

这里给出我对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的定义)

#31


不明真相围观当中

#32


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

//File2.h
using A::A01;

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

VS2005编译通过

#33


补充:


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

//File2.h
using A::A01;

//File2.cpp
#include "File1.h"    // 注意包含顺序,含有前向声明对象实现的单元要包含在前面
#include "File2.h"

#34


问一下,把namespace用在类的外部 有什么好处?什么情况下需要这么用?

#35


qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。

结论:一个玩wow玩出优越感的程序员。

#36



namespace boost
{
    class thread;
};

typedef boost::shared_ptr<boost::thread>    thread_pt;

这是我的代码

#37


引用
qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。

结论:一个玩wow玩出优越感的程序员。


确实 喷了半天都不明白楼主的意思  如果可以包含头文件解决还要前置声明这玩意吗  

我实验了不用typedef也可以
namespace sql
{
    class ResultSet;
}
using sql::ResultSet;

#1


class  A01::Aa;

#2


或者using A01::Aa;

#3


引用 1 楼 pengzhixi 的回复:
class  A01::Aa;


你好,这个,这么写,好像都出错了
环境:
visual studio 2010 sp1 + Intel Parallel Studio 2011 (编译器 Intel C++ Compiler 12.0 )



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

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

class A01::Aa; //前置声明放在这里

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

//编译器报错
Error 1 error : name followed by "::" must be a class or namespace name




---------换一个地方写 class A01::Aa; 


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

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



namespace B01{

class A01::Aa; //把这个前置声明放在namespace B01里面

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

//编译器报错
Error 1 error : name followed by "::" must be a class or namespace name




#4


你肯定得include"file01.h"

#5


引用 2 楼 pengzhixi 的回复:
或者using A01::Aa;


试了一下,如果 没有包含 ( #include “file01.h”)

在 file02.h 里面
using A01::Aa; //这一行,直接error : name followed by "::" must be a class or namespace name   


目前,试过的,可行的,不包含 file01.h
用 前置声明,
好像就只有 下面的写法


namespace A01{
class Aa; //前向声明A01中的类Aa;
}

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


#6


引用 4 楼 pengzhixi 的回复:
你肯定得include"file01.h"


如果 要包含 include"file01.h"
那似乎,就没有使用 前置声明 的意义了吧?

#7


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

#8


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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

#9


无解,不知道哪错了.....

#10


本来就只有一种写法,有啥好折腾的。

#11


引用 5 楼 candpointer 的回复:
namespace A01{
class Aa; //前向声明A01中的类Aa;
}

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

以前试过,这样写也是不可靠的,只声明不会有问题。如果使用这个类的话还与连接顺序有关。
最好把定义与实现分开,使用#include包含定义

#12


引用 8 楼 candpointer 的回复:
引用 7 楼 pengzhixi 的回复:

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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

如果仅仅是指针,不涉及成员调用,确实可以前置,而且是可靠的。

#13


引用 5 楼 candpointer 的回复:
目前,试过的,可行的,不包含 file01.h
用 前置声明,
好像就只有 下面的写法

有一种写法不就可以了,可能是C++标准就这样定义的吧(不太清楚)。

#14


楼主,你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;
}


#15


复制乱了。。自己看着弄吧。

#16


引用 14 楼 qq120848369 的回复:
楼主,你namespace学的很差火候,没法给你讲,真的。

#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; }



看了下,这个,head1.h,不是前置声明类T,(forward declaration)...
看你head2.h,这个 算是 前置声明
namespace A
{
    class T;

    int useT(const T &);
}


我是要在 另外一个 namespace B的头文件里面 使用 namespace A中的class T
只是需要 指针或引用,所以想在head2.h里面,只用 前置声明,而没必要包含head1.h

但,看你这个........

另外,所谓的
int /*看到我犯贱的全局作用域么? */::useT


其实,你这个 useT,还是属于 namespace A。


至于你下面的这个,如果真只是需要类T的定义。
完全可以
using A::T;
而不是完整地using A。


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



我只想告诉你,你的【int /*看到我犯贱的全局作用域么? */::useT】 其实,是属于 namespace A的。



你的的确有点乱。

#17


引用 12 楼 sbwwkmyd 的回复:
引用 8 楼 candpointer 的回复:
引用 7 楼 pengzhixi 的回复:

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


好像一般情况下,在file02.h 定义类Bb,如果,只是用到 类型Aa的 引用(reference) 或者 指针(pointer),就没必要包含 头文件file01.h(类Aa的定义)吧?

如果仅仅是……


好像,很多规范里面,都提到,避免太多的头文件依赖,要使用前置声明。
如果,只是用到 指针或者引用,是可以在头文件,安全地使用 前置声明的(forward declaration)
当然,如果用到了成员,那是需要完整地包含类的定义的头文件。

#18


引用 16 楼 candpointer 的回复:
[Quote=引用 14 楼 qq120848369 的回复:]

楼主,你namespace学的很差火候,没法给你讲,真的。

C/C++ code
#include <iostream> #include "head1.h" //为了用类T #include "head2.h" //为了用函数userT using namespace std; int main() { A::T ……


我知道说你差火候你就要喷我,所以我不在意,学习是你自己的,你完全可以当我放屁了.

#19


想学明白namespace,建议你去看看经常使用的各种头文件,例如:iostream,vector,map,set,你会发现,他们所有的模板定义与全局模板函数定义都是包括在_STD_BEGIN ,_STD_END里的。

为什么:

#include <iostream>
using namespace std;

vector<int> a; 提示找不到vector。

因为你没有包含<vector>,using std只是把iostream里的namespace std解开了。

如果你#include <vector>

那么iostream和vector在这里才知道原来彼此都在std里,大家一起暴露出来。

这就是我说的,std不过是个名字,在哪里用,谁也不知道,只有它们碰到一起的时候,才会累加起来。

#20


引用 17 楼 candpointer 的回复:
好像,很多规范里面,都提到,避免太多的头文件依赖,要使用前置声明。

我是初用C++,觉得#include用着挺方面,依赖层次多的话可以少写很多定义。
很想知道头文件有哪些缺陷?

#21


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




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

namespace B01 //我是帅哥B01,我在家乐福二层(file2.h). 我不认识A01,但我非常想知道她的身材好不好!
{ //那我必须先往下俯瞰一下,不仅要看看A01是谁,而且必须看看身材怎么样,这样才能意淫她!
class Bb
{
A01::Aa *ptrAa; //A01我见到了,身材也不错,是Aa的,我先意淫一下它的身材吧.
};
}

int main()
{
    return 0;
}

#22


ls扯的有点远

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

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

这个不行
class A01::Aa;

#23


楼主的问题其实不是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 *);

#24


引用 22 楼 cxyoooo 的回复:
ls扯的有点远

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

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

这个不行
class A01::Aa;


看23楼.

#25


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

#26


引用 25 楼 qq120848369 的回复:
以后看样不能嘲讽楼主了,仇恨太高,让楼主已经忘记了来干什么的。



你根本没有明白,不包含头文件,为什么只是使用到 前置声明(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后中的某部分人吧?

#27


引用 21 楼 qq120848369 的回复:
C/C++ code
namespace A01    //我是美女A01,我在家乐福一层(file1.h)
{
    class Aa 
    {
    }; 
}




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

namespace B01    //……



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

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

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



//file02.h

namespace A01{
class Aa; //前向声明A01中的类Aa;
}

#28


好的,我不会,你等其他人来回答,我围观。

#29


引用 27 楼 candpointer 的回复:
引用 21 楼 qq120848369 的回复:

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




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


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

你可以去看一下effective c++,只是个建议,你是高手,伤不起。 前向声明 另外一个命名空间中的类,有几种写法?

#30


引用 24 楼 qq120848369 的回复:
看23楼.


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

这里给出我对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的定义)

#31


不明真相围观当中

#32


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

//File2.h
using A::A01;

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

VS2005编译通过

#33


补充:


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

//File2.h
using A::A01;

//File2.cpp
#include "File1.h"    // 注意包含顺序,含有前向声明对象实现的单元要包含在前面
#include "File2.h"

#34


问一下,把namespace用在类的外部 有什么好处?什么情况下需要这么用?

#35


qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。

结论:一个玩wow玩出优越感的程序员。

#36



namespace boost
{
    class thread;
};

typedef boost::shared_ptr<boost::thread>    thread_pt;

这是我的代码

#37


引用
qq120848369 这位朋友的确有点自以为是,欠缺点技术上的谦卑,自信是好事,但是不要第一句话就开始喷。就lz的这个问题,qq120848369的确是一点都不懂。

结论:一个玩wow玩出优越感的程序员。


确实 喷了半天都不明白楼主的意思  如果可以包含头文件解决还要前置声明这玩意吗  

我实验了不用typedef也可以
namespace sql
{
    class ResultSet;
}
using sql::ResultSet;