zoukankan      html  css  js  c++  java
  • C++类的交叉引用

    对于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
    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
    这里我们只是告诉编译器,我们有这么一个类存在,不是一般的错误或者什么重定义乱定义之类的。
    然后在另两个文件中加类的成员函数的实现代码:

    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. }
    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中,我们都分别引用了对方的头文件,这回我们就得知道对方类的
    成员函数有哪些了,以及其函数接口。









  • 相关阅读:
    class(类)和构造函数(原型对象)
    es6中export和export default的区别
    vue混入 (mixin)的使用
    ES6(Module模块化)
    vue-cli3构建和发布 实现分环境打包步骤(给不同的环境配置相对应的打包命令)
    Vue中使用Echarts 脱坑
    Nginx配置详解
    VUE面包屑组件
    更改 pip 默认下载源(pip 配置文件)
    常见免费API接口
  • 原文地址:https://www.cnblogs.com/yml435/p/4664372.html
Copyright © 2011-2022 走看看