小弟正在做多媒体相关的应用,现阶段正在写接口,不知设计是否完善,希望得到大家的指点

小弟正在做多媒体相关的应用,目前正在写接口,不知设计是否完善,希望得到大家的指点
小弟的开发平台是win64 VS2010
直接上代码:


MediaService.h
#pragma once

#include <string>
#include <list>

#include "talk/base/scoped_ptr.h"
#include "talk/xmpp/xmppthread.h"
#include "talk/xmpp/xmppclient.h"

// 名字空间multimedia,包含CMediaService、CMedium等所有媒体相关组件
namespace multimedia
{

// XMPP状态枚举:重定向枚举值,解耦用户和第三方库之间的联系,降低用户使用接口的复杂度
enum EXmppState
{
E_XMPP_STATE_NONE    = buzz::XmppEngine::STATE_NONE,  
E_XMPP_STATE_START   = buzz::XmppEngine::STATE_START,
E_XMPP_STATE_OPENING = buzz::XmppEngine::STATE_OPENING,
E_XMPP_STATE_OPEN    = buzz::XmppEngine::STATE_OPEN,   
E_XMPP_STATE_CLOSED  = buzz::XmppEngine::STATE_CLOSED
};

// 观察者模式:用户通过实现该接口,并将实现后的实例加入观察者队列,可监听随机事件XmppStateChange
class IXmppStateObserver
{
public:
virtual void XmppStateChange(const EXmppState& newXmppState) = 0;
};

class CMedium;

enum EMediumType
{
E_MEDIUM_PRESENCE,          // 出席状态
E_MEDIUM_CHAT,              // 文字、表情、图片等聊天
E_MEDIUM_PEERCONNECTION,    // 声音、视频实时通讯
E_MEDIUM_CONFERENCE,        // 会议
E_MEDIUM_RECORD,            // 录像
E_MEDIUM_PLAYBACK           // 媒体回放
};

class CMediaService : public sigslot::has_slots<>
{
public:
// 单例模式
static CMediaService& GetInstance(void)
{
/* 这种单例模式实例化方式是所有单例模式设计中比较优秀的一种,较好地解决了如下问题:
   1.多线程访问:采用局部静态变量的方式将多线程访问保护丢给操作系统,因为对于静态变量,
   操作系统会保证其仅被初始化一次,所以用户不必刻意加锁以保证实例的唯一性;
   2.实例销毁时机:如果采用在堆上实例化单例模式,则需考虑的一个问题是何时销毁该实例(这种情况在动态库中较难处理),
   如果销毁时机不当,会导致之后的调用出错,增加了用户维护该实例的难度;
   3.IO资源释放:单例模式中很可能在构造函数中初始化了一些IO资源,而这些资源要等到析构函数调用时才释放,那么,
   如何保证析构函数一定被调用且时机得当?由于静态局部变量存储于静态存储器中,当程序退出时系统会自动释放静态存储区中的对象,
   所以,局部静态实例的析构函数被系统自动调用,即保证了析构函数被调用,又保证了一定在程序退出时在调用,一举两得;
   4.饿汉懒汉:饿汉方式可以保证实例一定存在,但如果用户没有用到该实例,则会造成内存的浪费,
   而局部静态变量则由系统保证其在第一次被使用时初始化,且被初始化一次,是一种巧妙的饿汉模式;
   (备注:delete操作符的作用:1.调用被操作对象的析构函数,2.将对象占用的内存返还给堆)
*/
static CMediaService sMediaService;
return sMediaService;
}

// m_pXmppClient不允许在外部修改,所以返回const指针的引用,以防止意外复制和修改
buzz::XmppClient * const & GetXmppClient()
{
// 通过m_pXmppClient->jid()可以得到自己的login ID,该ID格式为“用户名@域/资源”,具体参考class Jid定义
return m_pXmppClient;
}

void DoLogin(std::string& usrName, 
         const std::string& passWd,
         const std::string& serverIPAddr, 
         const std::string& resourceName = "");
void DoLogout();

/* 1.该接口实现的是所有媒体组件的简单工厂模式,即所有媒体组件都从CMedium基类派生,创建时只需指定一个组件枚举ID,
   由该接口在堆上创建组件并返回一个CMedium基类指针,而用户需要使用dynamin_cast操作符将基类指针转为具体的媒体组件,
   从而调用各组件上的特有方法;
   2.所有媒体组件的构造函数和析构函数都定义为私有函数,从而不允许用户直接创建媒体组件,
   而CreateMedium函数为各媒体组件的友元函数,从而可以创建该类的实例,达到集中创建的目的。
*/
CMedium* CreateMedium(const EMediumType& eMediumType);
/* 1.DestroyMedium函数为所有媒体组件的友元函数,从而可以销毁该类的实例,达到集中销毁的目的;
   2.传入参数为指针的引用,删除实例后将指针置为NULL并通过引用传出,在一定程度上可防止外部对无效实例的使用。
*/
void DestroyMedium(CMedium* & pMedium);

private:
CMediaService(void);
~CMediaService(void);

void OnXmppStateChange(const buzz::XmppEngine::State state);
void NotifyXmppStateObserver(const EXmppState& newXmppState);

private:
static const int                             DEFAULT_XMPPSERVER_PORT = 5222;

/* talk_base::scoped_ptr<T>属于智能指针,不用显式调用delete删除,系统会自动回收,
   所以,该类型的成员变量随着宿主类对象的消亡而消亡
*/
talk_base::scoped_ptr<talk_base::Thread>     m_pXmppThread;
talk_base::scoped_ptr<buzz::XmppPump>        m_pXmppPump;
buzz::XmppClient*                            m_pXmppClient;
buzz::XmppClientSettings                     m_xmppClientSetting;
/* list当中存放元素的拷贝,所以当以指针为参数时,一定要注意指针的有效性,
   即当指针所指对象被在某处释放时,要同步更新list中的数据,否则可能引起野指针调用。
   C++允许引用多态,但list不允许引用参数,所以此处使用指针,const的作用是防止对象被意外修改
*/
typedef std::list<IXmppStateObserver* const> XmppStateObserverList_t;
XmppStateObserverList_t                      m_lstXmppStateObserver;