1. 程式人生 > 其它 >C++_類互相包含

C++_類互相包含

技術標籤:C++c++

C++ 類相互包含分析

C++類相互包含

問題描述

兩個類,Class A和Class B,定義時,Class A用到了Class B, Class B用到了Class A.

假設有兩個類,如下

  • ClassA.h
#include "ClassB.h"
class A
{
public:
	int m_valueA;
	B	m_b;
}
  • ClassB.h
#include "ClassA.h"
class B
{
public:
	int m_valueB;
A m_a; }

但是上面這種情況,在編譯的時候,會出現錯誤,比如

B.h中使用了未知型別的Class A.

分析

在上述的情況下,編譯器在編譯的時候,Class A會包含Class B, 所以就去檢視B的佔用空間的大小,但是檢視的時候,又發現需要知道A的佔空間的大小。會出現A中包含B,B中包含A, A.B.A.B…無線迴圈的情況。

解決方法

  • Class A
    在Class A中宣告Class B,但是不包含Class B的標頭檔案
/*這是a.h標頭檔案*/
#ifndef A_H
#define A_H

class B					//注意:單純的宣告Class B;

class A
{
    .
.. //A的一些宣告 B* m_b_ptr //注意:僅能在class A裡使用class B的指標或者引用 } #endif
  • ClassB
    在Class B中新增Class A的標頭檔案
/*這是b.h標頭檔案*/
#ifndef B_H
#define B_H

#include"A.h"			//注意:宣告A的標頭檔案

class B
{
    ...					//B的一些宣告
    A 	m__a_object		//Class A物件, A的標頭檔案匯入了B的標頭檔案,就可以不使用指標
    A* 	m_a_ptr			//Class A指標
}
#endif

原因

在A中用指標呼叫B,那麼在A需要知道B佔空間大小的時候,就會去找到B的定義檔案,雖然A的定義檔案中並沒有匯入B的標頭檔案,不知道B的佔用大小,但是由於在A中呼叫B的時候用的指標形式,A只知道指標佔用4個位元組就可以,不需要知道B真正佔用空間大小。但是B中incude了A的標頭檔案,所以B是知道A佔用空間大小的。

注意:

A.h中包含B.h, B.h中包含A.h。編譯時不能通過。

測試例程

  • Class Person
#include <iostream>
#include <string>

#include "Phone.h"		//注意:新增class Phone定義的標頭檔案

using namespace std;

class Person
{
public:
	Person(string personName, string phoneType)
	{
		m_Name = personName;
		m_phone.setOwner(this);
		cout << "Person and Phone constructure fun" << endl;
		cout << "Person object  address: " << m_phone.getPersonPtr() << endl;
		cout << "Person object this address: " <<this << endl;
	}
	
	~Person()
	{
		cout << "This is de-constructure fun" << endl;
	}
	
	string m_Name;		//person Name
	Phone m_phone;		//注意,這裡可以直接使用Phone的定義而非指標
}

  • Class Phone
#include <iostream>
#include <string>

using namespace std;

class Person;	//注意,這裡只需要宣告Person, 在Phone.h中不包含Person.h

class Phone 
{
public:
	Phone();
	{
		cout << "this is phone default constructure fun" << endl;
	}

	~Phone()
	{
		cout << "this is phone  de-constructure fun" << endl;
	}
	
	Phone(string name);
	
	void setOwner(Person *personPtr)		//設定屬於哪個Person
	{
		if (personPtr!=NULL)
		{
			m_personPtr = personPtr;
		}
	}
	
	Person *getPersonPtr(void)
	{
		return m_personPtr;
	}
	
	string m_phoneName;

private:
	Person *m_personPtr;

};
  • test函式
#include "Person.h"

int main()
{
	Person p("Zhang San", "Sumsun");
	system("Pause");
	return 0;
}

測試結果

可以看到Class Phone中的指向Person的指標,和當前Person物件內部的this指標的值相同。
在這裡插入圖片描述