1. 程式人生 > >C++設計技巧(一)之兩個類互相擁有對方的物件指標

C++設計技巧(一)之兩個類互相擁有對方的物件指標

1、在實際的運用中我們也會用到如下的類關係:

class B;
class A
{
int i;
B  *lpb;
}

class B
{
int i;
A* lpa;
}

注意:一般來說,兩者的定義,至少有一方是使用指標,或兩者都使用指標,但是決不能兩者都定義實體物件。

這樣的實現,通俗地來說是 “你中有我,我中有你 ”,那麼在具體運用時,我們可以將兩個類所實現的含義聯絡起來,比如我們說A類的物件為一個一個的請求,B類物件表示會話(會話有相應的操作介面),此時只要A類和B類擁有對方的物件指標,如上程式碼所示,我們就可以將一個請求和一個會話,一一對應起來,當我們得到一個請求後,我們也就能得到這個請求對應的會話操作。

2、測試用例

class EventDownloadSession;

class OpenModelEventDownload      //該類我們可以提供給外部使用
{
public:
	OpenModelEventDownload(): bSynchronization(true)
       {
           
        }
	virtual ~OpenModelEventDownload()
        {

        }
	virtual void dealloc()
        {
             delete  this;
        }

	static OpenModelEventDownload * alloc()
        {
            OpenModelEventDownload * lpValue = new OpenModelEventDownload();
		lpValue->AddRef();
		return lpValue;
       }

	inline void setFilePath(const char * value)
	{
		filePath = value;
	}
	inline const char * getFilePath()
	{
		return filePath.c_str();
	}

	inline void setFileSize(size_t value)
	{
		fileSize = value;
	}
	inline size_t getFileSize()
	{
		return fileSize;
	}
	inline void setFileSeek(size_t value)
	{
		fileSeek = value;
	}
	inline size_t getFileSeek()
	{
		return fileSeek;
	}

	inline void setDownloadUrl(const char * value)
	{
		downloadUrl = value;
	}
	inline const char * getDownloadUrl()
	{
		return downloadUrl.c_str();
	}
	inline void setDownloadProcess(int32_t value)
	{
		downloadProcess = value;
	}
	inline int32_t getDownloadProcess()
	{
		return downloadProcess;
	}

	inline void setSynchronization(bool value)
	{
		bSynchronization = value;
	}
	inline bool getSynchronization()
	{
		return bSynchronization;
	}

//注意如下的兩個介面
	inline OpenCloud::EventDownloadSession * getEventDownloadSession()
	{
		return downloadSession;
	}
	inline void setEventDownloadSession(OpenCloud::EventDownloadSession *lpSession)
	{
		downloadSession = lpSession;
	}
private:
	std::string   filePath;
	size_t        fileSize;
	size_t        fileSeek;

	bool          bSynchronization;
	
	std::string            downloadUrl;
	int32_t                downloadProcess; //[0,100]
	EventDownloadSession * downloadSession;     //下一個物件指標
};

//基類
class  EventDownloadSession       
{
public:
	EventDownloadSession(OpenCloud::OpenModelEventDownload *lpOpenModelEventDownload)
		:kOpenModelEventDownload(lpOpenModelEventDownload)
	{}
	virtual ~EventDownloadSession()
	{}

	virtual int stopSession() = 0;

public:
	OpenCloud::OpenModelEventDownload *kOpenModelEventDownload;    //上一個類的物件指標
};

//派生類
class EventOperationDownloadSession : public EventDownloadSession
{
public:
	EventOperationDownloadSession(OpenCloud::OpenModelEventDownload *lpOpenModelEventDownload):EventDownloadSession(lpOpenModelEventDownload)
	{
		
	}
	virtual ~EventOperationDownloadSession()
	{}
	virtual void dealloc(void * ref)
	{
		delete this;
	}
	static EventOperationDownloadSession * alloc(OpenCloud::OpenModelEventDownload *lpOpenModelEventDownload)
	{
		EventOperationDownloadSession *lpEventOperationDownloadSession = new EventOperationDownloadSession(lpOpenModelEventDownload);
		return lpEventOperationDownloadSession;
	}
	virtual int Init(void * conf)
	{
             //do something
	     return 0;
	}

	virtual int Close()
	{
            //do something
             return 0;
	}

	virtual int stopSession()
	{
              //do something
	     return 0;
	}
public:
	
};

int main()
{
     int iSsuccess  =0;
     OpenModelEventDownload *lpOpenModelEventDownload = OpenModelEventDownload::alloc();
     lpOpenModelEventDownload->setFilePath("/tmp/123456.mp4");
     
     EventOperationDownloadSession *lpEventOperationDownloadSession =  EventOperationDownloadSession::alloc(lpOpenModelEventDownload );
	download->setEventDownloadSession(lpEventOperationDownloadSession);

    iSsuccess = lpEventOperationDownloadSession->Init(nullptr);   
    //do something
  
return 0;
}