对于C++中,两个类中相互引用对方,当然只能是在指针的基础上,于是我们知道。也就是说在A类的有一个指针引用B类的成员函数或成员对象,而B类中又有一个指针来访问A中的成员函数或对象。这就是C++中类的交叉引用编译于。那如何解决这个问题呢?
当然方法很多,但是我一般采用的方法就是声明与实现的分离。
也就是说类中的成员函数我们只在类中声明,然后函数的实现要放到另一个文件中去。
主要是在类中的交叉引用时候,存在一个谁先谁后的问题,也就是说假如A类中用B的指针引用了B的一个成员函数,如果B中没有引用A的成员,那问题好办,我们先在A类的头文件中引用B的头文件,于是我们保证先编译B,然后再编译A。
但是我们如果在B中也有一个A的指针引用了A的成员函数呢?
那么是先编译A还是先编译B呢? 如果先编译A,那么A中引用了B的成员函数,B还没编译呢! 如果先编译B,而B中又引用了A的成员函数呢!
这样就想当于死锁或者不停地迭代。那么如何解决呢?
方法就是先声明,再定义。直接看我们的解决方法:


class Observer(Observer.h)

  1. #ifndef OBASER_H
  2. #define OBASER_H
  3. #include"Observerable.h"
  4. class Observerable;
  5. class Observer{
  6. private:
  7.    Observerable *subject_;
  8. public:
  9.    virtual void update(){};
  10.    void observer(Observerable *s);
  11.    ~Observer();
  12. };
  13. #endif
class Observerable(Observerable.h)
  1. #ifndef OBASERVERABLE_H
  2. #define OBASERVERABLE_H
  3. #include<iostream>
  4. #include<vector>
  5. #include<algorithm>
  6. class Observer;
  7. class Observerable{
  8. private:
  9.    std::vector<Observer*> obsPtrs;
  10. public:
  11.    void register_obs(Observer *obs_);
  12.    void unregister_obs(Observer *obs);
  13.    void notificate_obs();
  14. };
  15. #endif
我们可以看到在两个类中,对对方都加了一次声明如:
class Observer
class Observerable
这里我们只是告诉编译器,我们有这么一个类存在,不是一般的错误或者什么重定义乱定义之类的。

然后在另两个文件中加类的成员函数的实现代码:

Observer.cpp

  1. #include"Observer.h"
  2. #include"Observerable.h"
  3. void Observer::observer(Observerable *s){
  4.    s->register_obs(this);
  5. }
  6. Observer::~Observer(){
  7.    subject_->unregister_obs(this);
  8. }
Observerable.cpp
  1. #include"Observerable.h"
  2. #include"Observer.h"
  3. void Observerable::notificate_obs(){
  4.    for(int i=0;i<obsPtrs.size(); i++){
  5.        if(obsPtrs[i]){
  6.            obsPtrs[i]->update();
  7.        }
  8.     }
  9. }
  10. void Observerable::register_obs(Observer *obs_){
  11.        obsPtrs.push_back(obs_);
  12.    }
  13. void Observerable::unregister_obs(Observer *obs){
  14.    std::vector<Observer*>::iterator obsIter;
  15.    if((obsIter=std::find(obsPtrs.begin(),obsPtrs.end(),obs))!=obsPtrs.end()){
  16.        obsPtrs.erase(obsIter);
  17.    }
  18. }
而且在两个具体实现的文件中如Observerable.cpp和Observer.cpp中,我们都分别引用了对方的头文件,这回我们就得知道对方类的
成员函数有哪些了,以及其函数接口。

C++类的交叉引用的更多相关文章

  1. Word交叉引用

    第一种:参考文献,用NE插入. 第二种:交叉引用. 先定义新的编号格式[1](主要解决参考文献格式自动编号的问题),感觉但是没有解决缩进的问题,需要Tab. 但是实验发现,通过谷歌学术引用的参考文献插 ...

  2. 交叉引用:Microsoft.NET标准异常 和错误代码对照表

    简介 此表旨在帮助将Windows运行时应用程序错误代码交叉引用到Microsoft.NET标准异常,这些异常可以作为应用程序异常处理技术的一部分. 对照表 .NET Exception (Names ...

  3. C++学习笔记一 —— 两个类文件互相引用的处理情况

    先记录一些零碎的知识点: 1. 一个类可以被声明多次,但只能定义一次,也就是可以 class B;  class B;  class B; ……;  class B {……};  这样子. 2. 一个 ...

  4. Word2013对公式处理:样式、自动编号、交叉引用

    因快写毕业论文,专门研究了一下Word2013对公式的处理,有一点小心得,记在这里. 文章中公式展示的预期效果是:公式居中,尾端有编号,同时在文章中可以实现引用.实现该效果有很多方法,这里就说一种,其 ...

  5. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

  6. WPS2012交叉引用技巧,word比wps这点强更新參考文献

                WPS2012交叉引用技巧,word比wps这点强更新參考文献 到时生成仅仅有有一条线,好像WPS不能够,word能够,假设谁知道能够补充.^_^ 1.写论文,參考文献的改动非 ...

  7. C++中基类对象的引用

    代码: #include <iostream> #include <cstdio> using namespace std; class A{ public: void pri ...

  8. WPS2012交叉引用提示word比wps这种强烈的更新参考

                WPS2012交叉引用技巧,word比wps这点强更新參考文献 到时生成仅仅有有一条线,好像WPS不能够,word能够,假设谁知道能够补充.^_^ 1.写论文,參考文献的改动非 ...

  9. word交叉引用公式编号时和连公式一起引用

    如下所示: 假定一副待处理图像中的灰度值个数为m,灰度值为i的像素个数为 个,那么图像中的总像素数为N,公式如m=x+y (2)所示: m=x+y                            ...

随机推荐

  1. KeyValuePair

    KeyValuePair用法(转)(2012-06-25 10:47:35) 转载▼ // 标签: keyvaluepair it   KeyValuePair C# KeyValuePair< ...

  2. 12月14日《奥威Power-BI销售计划填报》腾讯课堂开课啦

           2016年的最后一个月也过半了,新的一年就要到来,你是否做好了启程的准备?新的一年,有计划,有目标,有方向,才不至于迷茫.规划你的2017,新的一年,遇见更好的自己!        所以 ...

  3. Nginx下配置SSL安全协议

    生成证书: # cd /usr/local/nginx/conf # openssl genrsa -des3 -out server.key 1024 # openssl req -new -key ...

  4. MVC_表单和HTML辅助方法

    表单的使用 action特性告知Web浏览器信息发往哪里. method特性告知浏览器使用HTTP POST 还是 HTTP GET. GET请求用于读操作, POST请求用于写操作 HTML辅助方法 ...

  5. 关于 Android 5.0 原生系统网络图标上的感叹号问题解决方法

    解决方案 adb shell settings put global captive_portal_server g.cn 参考 关于 android 5.0 网络图标上的感叹号及其解决办法

  6. Eclipse中使用自己封装的jar包的过程

    在包名上右键,选择Export"" 经过上面的步骤,成功导出了可运行jar包,下面在另一个自己的工程里引入这个jar包 最终效果如下:可见包已经可以正常使用了!! 运行自己的jar ...

  7. Form 数据库的顺序

    form buidler 中数据库的上下排列顺序也很重要,开发中无心把LINE的数据块放在HEADER数据块之上, 导致在新增数据的时候先去insert  LINE数据块(没有生成HEADER_ID的 ...

  8. iOS中UIWebView与其中网页的javascript的交互

    首发:个人博客,更新&纠错&回复 1.本地语言调js的方式与android中的方式类似,也是向WebView控件发送要调用的js语句 2. 但js调本地语言,则不是像android那样 ...

  9. javaWeb 使用 filter 处理全站乱码问题

    1. web.xml文件中的配置 <filter> <filter-name>CharacterEncodingFilter</filter-name> <f ...

  10. js页面刷新之实现框架内外刷新(整体、局部)

    这次总结的是框架刷新: 框架内外的按钮均可以定义网页重定向, 框架内部页面的按钮可以实现局部刷新, 框架外部页面的按钮可以实现整页刷新. 代码如下(两个html页面): <!--主界面index ...