C++,類的前置聲明,c++繼承,c++子類訪問父類成員變量,c++頭文件相互包含

假設聲明兩個類A和B,如果需要在A.h中定義B類對象,B b_; 勢必要包含# include “B.h”,而B類中需要定義A類對象A a_; 也要包含B.h,但是相互包含是不允許的,稱爲環形引用,這時候就用到了前向聲明

1,a.h 類A中實例化類B的對象

#ifndef __A_H__
#define __A_H__

#include <iostream>
#include <stdio.h>
#include "b.h" //類A中要實例化一個類B的對象

class BasicA {
protected:
    int m_a = 1;
public:
    void print_a2() {
        std::cout << "a2:" << m_a << std::endl; 
    };
};

class A : public BasicA {
private:
    B m_b;//例化一個類B的對象
public:
    A();
    ~A();
    void print_a();
    void print_this();
};
#endif

2,a.cpp 可以調用類B對象的方法

A::A() {
    std::cout << "this->p:" << (void *)&m_a << std::endl;
    m_b.set_a(this); //將類A的真實指針傳給類B
}
A::~A(){
}
void A::print_a() {
    m_a = 2;
    std::cout << "a:" << m_a << std::endl; 
    m_b.print_b(); //調用類B對象的方法
}
void A::print_this() {
    std::cout << "a this" << std::endl;
}

3,b.h 類B中不能實例化類A的對象

#ifndef __B_H__
#define __B_H__
#include <iostream>

class A; //類A的前置聲明

class B{
private:
    int m_b = 1;
    A *m_a; //定義一個類A的指針,用作佔位
public:
    B();
    ~B();
    void set_a(A *a); //用於將實際的類A的指針傳進來
    void print_b();
};
#endif

4,b.cpp 中包含a.h,這樣就可以使用類A對象中的方法

#include "b.h"
#include "a.h"

B::B(){}
B::~B(){}

void B::set_a(A *a) {
    m_a = a;
    std::cout << "ma->p:" << (void *)m_a << std::endl;
}

void B::print_b() {
    std::cout << "b:" << m_b << std::endl; 

    m_a->print_this(); //使用類A對象的方法
}

5,main.cpp

#include <iostream>
#include "a.h"

int main() {
    A a;
    a.print_a2();
    a.print_a();
    std::cout << "111111111111111111111111" << std::endl;
}

6,運行

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章