我是靠谱客的博主 怡然老虎,最近开发中收集的这篇文章主要介绍友元的互相依赖问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

       友元,是一种对非成员函数或类提供私有成员访问权限的机制。以关键字friend声明,通常出现在类的起始或结尾处。但是实际使用中也容易碰到友元声明与定义之间的互相依赖问题。

        例子如下,我们对Mutex和Condition Veriable进行封装,由于条件变量的等待函数需要操作原始pthread_mutex_t对象,因此我们需要将条件变量的类声明为Mutex类的友元。我们先封装Mutex。这里包含了我们自己封装的条件变量头文件cond.h,并声明为其友元。

#ifndef __MUTEX_H__
#define __MUTEX_H__
#include <pthread.h>
#include "cond.h"
namespace Pthread
{
class IUncopyable
{
public:
IUncopyable(){};
private:
IUncopyable(IUncopyable &);
IUncopyable & operator=(const IUncopyable&);
};
class IMutex
{
public:
virtual ~IMutex(){};
virtual int lock() = 0;
virtual int trylock() = 0;
virtual int unlock() = 0;
};
class CMutex: public IMutex, private IUncopyable
{
friend class CCond;
public:
CMutex();
~CMutex();
int lock();
int trylock();
int unlock();
private:
pthread_mutex_t m_mutex;
};
class CGuard
{
public:
CGuard(IMutex *mutex): m_mutex(mutex){m_mutex->lock();};
~CGuard(){m_mutex->unlock();};
private:
IMutex *m_mutex;
};
}
#endif
#ifndef __MUTEX_H__
#define __MUTEX_H__
#include <pthread.h>
#include "cond.h"
namespace Pthread
{
class IUncopyable
{
public:
IUncopyable(){};
private:
IUncopyable(IUncopyable &);
IUncopyable & operator=(const IUncopyable&);
};
class IMutex
{
public:
virtual ~IMutex(){};
virtual int lock() = 0;
virtual int trylock() = 0;
virtual int unlock() = 0;
};
class CMutex: public IMutex, private IUncopyable
{
friend class CCond;
public:
CMutex();
~CMutex();
int lock();
int trylock();
int unlock();
private:
pthread_mutex_t m_mutex;
};
class CGuard
{
public:
CGuard(IMutex *mutex): m_mutex(mutex){m_mutex->lock();};
~CGuard(){m_mutex->unlock();};
private:
IMutex *m_mutex;
};
}
#endif

   接下来我们对条件变量封装,由于先前在CMutex类中声明了CCond为友元,因此这里可以对其private成员操作。

#ifndef __COND_H__
#define __COND_H__
#include <pthread.h>
#include "mutex.h"
namespace Pthread
{
class ICond
{
public:
virtual ~ICond(){};
virtual int wait(CMutex &) = 0;
virtual int signal() = 0;
virtual int broadcast() = 0;
};
class CCond: public ICond
{
public:
CCond();
~CCond();
int wait(CMutex &);
int signal();
int broadcast();
private:
pthread_cond_t m_cond;
};
}
#endif
#include "cond.h"
namespace Pthread
{
CCond::CCond()
{
pthread_cond_init(&m_cond, NULL);
}
CCond::~CCond()
{
pthread_cond_destroy(&m_cond);
}
int CCond::wait(CMutex &mutex)
{
return pthread_cond_wait(&m_cond, &mutex.m_mutex);
}
int CCond::signal()
{
return pthread_cond_signal(&m_cond);
}
int CCond::broadcast()
{
return pthread_cond_broadcast(&m_cond);
}
}


    接下来是编译,但是编译却出错了,那是由于mutex.h与cond.h互相依赖了,那么怎么解开呢?我们知道当对象定义为指针或引用时,编译器是确定了它的占用空间的,即sizeof(void *)。比如说CMutex *mutex,编译器并不需要知道CMutex类的占用空间。所以我们在int CCond::wait(CMutex &mutex)使用了CMutex的引用。那么可以将cond.h的#include "mutex.h"放入cond.cpp中,再于cond.h中声明一句class CMutex, 告诉编译CMutex是个类即可。




最后

以上就是怡然老虎为你收集整理的友元的互相依赖问题的全部内容,希望文章能够帮你解决友元的互相依赖问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部