• 7694阅读
  • 9回复

类的向前声明-你能看出它有什么错误吗 [复制链接]

上一主题 下一主题
离线rootlife
 

只看楼主 倒序阅读 楼主  发表于: 2010-09-07
— 本帖被 XChinux 执行加亮操作(2010-09-07) —
#include<QtCore/QCoreApplication>

class classb ;

class classa
{
       classb *pb;
public:
       void fun() {
            pb->exe();
       }
};


class classb
{
public;
       void exe() { qDebug("aaaaaaaaaa"); }
};

[ 此帖被rootlife在2010-09-27 13:07重新编辑 ]
离线dbzhang800

只看该作者 1楼 发表于: 2010-09-07
有错就贴出错消息

总不是让你问下面你这句的含义吧?

       class *pb;
离线rootlife

只看该作者 2楼 发表于: 2010-09-07
回 1楼(dbzhang800) 的帖子
想看错误就自己编译下, 如果你对类的向前声明很熟,  一看就知道是什么问题了. 编译器无法支持这种编译.   这算是一种考试. 我被难住了.  

我估计能让它编译通过的程序员恐怕没几个,   不过报着一丝希望贴在这里, 希望将来能有更优秀的编译器不要再出现这种问题.
离线dbzhang800

只看该作者 3楼 发表于: 2010-09-07
哦,我还你为你是让大家找拼写错误呢。

贴代码最好是直接从真实的代码中拷吧,能有效避免拼写错误
离线wd007

只看该作者 4楼 发表于: 2010-09-07
错误信息在哪里?
欢迎访问我的博客,一起学习提高
http://blog.csdn.net/qter_wd007
离线dbzhang800

只看该作者 5楼 发表于: 2010-09-07
引用第4楼wd007于2010-09-07 22:52发表的  :
错误信息在哪里?


楼主可能是想让人指出 类型不完全那个问题吧 (因为编译器看到他在fun函数内调用类b的成员函数时,还看不到类b的定义)

只是,楼主上面拼写错误,加上语义问题 (野指针pb),让人有点不知所措
离线rootlife

只看该作者 6楼 发表于: 2010-09-09
关于两个类的相互引用时的类型不完全问题, 主要是在下面的情况下会出现:

将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的指针, 类B定义了类A的指针;

将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的指针, 类B定义了类A的对象

将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的对象, 类B定义了类A的指针

将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的对象, 类B定义了类A的对象

前面三种情况只要分做两个文件(.h 和 .cpp)实现, 并且 类A不在头文件当中 涉及任何 类B的函数或成员变量, 然后将类A的涉及类B的成员的调用全部在CPP文件中实现, 即可编译完成.

最后一种情况无论怎样都是不会编译完成的, 也就是说是坚决不允许的.


编译器编译需数个阶段,先是.h,宏定义的转化替换,C++编译器还要预先提取H文件中的类信息.

由于C++编译实现不够完善,不能将互相用指针调用的两个类在一个文件中完成提取(尽管我觉得编译器完全可以通过再加一次预处理进行前后类信息对照来完成),故而会有这种错误. 目前必须进行分离才能通过编译.

为什么不能完善提取类信息. 需要学编译原理的人来做较为详细的解答. 也有一种可能是因为编译器的作者觉得没有必要这样做,因为要耗费不少工作量, 延长编译速度, 故而要求程序员进行手动分离.不过可能性太小了. 目前没有想到合适的理由来证明C++编译器为什么不支持这种编译.

下面贴出一个类相互引用可以成功的例子, 仅供参考.

//.h文件.
class classb;

class classa
{
public:
    classa();
    classb *pb;
    void exe();
    void fun()
    {
        int a=100;
        a+=10;
    }

};

class classb
{
public:
    classa *pa;
    classb( ) {
    }
    void fun() {
        int a=10;
        a+=10;
        pa->fun();
    }
};

//cpp 文件中这样实现:

#include "classa.h"

classa::classa()
{

}

void classa::exe()
{
    pb->fun();
}
[ 此帖被rootlife在2010-09-10 18:55重新编辑 ]
离线dbzhang800

只看该作者 7楼 发表于: 2010-09-10
引用第6楼rootlife于2010-09-09 22:53发表的  :
关于两个类的相互引用时的类型不完全问题, 主要是在下面的情况下会出现:
将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的指针, 类B定义了类A的指针;
将两个类的声明与实现全部放在一个文件中. 并且类A定义了类B的指针, 类B定义了类A的对象
.......


个人觉得不需要搞这么复杂吧。简单一点,大致可以这么来理解:

1. #include 只是编译预处理指令,只要理解它只是简单地把其他文件的内容贴到这个文件中就够了。
     这样一来讨论这个问题我们可以:不需要关心几个文件,不需要关心.h .cpp是否分离

2. 指针和对象不同,指针大小固定的,只要有声明就能定义指针。但由于没有类定义,你无法定义对象(包括用new分配对象)

3. 在使用一个对象时,你只需要看看使用之前该类有没有定义就够了。
(一般一个cpp是一个编译单元,有include的就将其在此处展开)。
比如你的例子,在你使用b(调用b的成员时),类b尚未定义。显然出错了。
离线billlee
只看该作者 8楼 发表于: 2010-09-26
class* pb
有这个语法吗?楼主原创的?
离线hqd_2008
只看该作者 9楼 发表于: 2010-11-03
回 6楼(rootlife) 的帖子
正解。
快速回复
限100 字节
 
上一个 下一个