设计一个包含多种功能的优秀C ++包装器类

时间:2014-11-01 15:42:59

标签: c++ oop design-patterns wrapper

我想在C ++中设计一个使用FTP,SFTP实现文件传输的包装器类。

我有一个由派生类FileTransfer继承的基类FTP(使用curl)。我需要支持SFTP,所以我实现了另一个派生类SFTP,它也继承自FileTransfer

我正在沿着以下行创建一个包装器类代码。但是,这看起来并不像是一个好的设计。我对OOP比较陌生,虽然我过去曾在C上工作过。



class Wrapper {
  public:
  Wrapper(int m_protocol){
    protocol = m_protocol;
    if (protocol)
      pftp = new FTP();
    else
      psftp = new SFTP();
  }
  
  ~Wrapper() {
    if (protocol)
      delete pftp;
    else
      delete psftp;
  }
  //Function supported by both ftp/sftp
  void do_something(){
    if (protocol)
      pftp->do_something();
    else 
      psftp->do_something();
  }
  
  //FTP specific function
  void use_passive(){
    assert(protocol);
    pftp->use_passive();
  }
  
  //SFTP specific function
  void ssh_key(){
    assert(!protocol);
    psftp->ssh_key();
  }
  
  private:
   int protocol;
   FTP *pftp;
   SFTP *psftp;
};




如何改进此设计?如何避免对每个函数进行if (protocol)检查并提高代码质量?我应该使用void指针psftp和' pftp`吗?

编辑:我正在使用包装器,因为在项目的很多地方,正在使用现有的FTP对象,如果我为SFTP使用单独的类(没有包装器),我将不得不添加{{1每次检查也支持SFTP。我不想将详细信息(FTP / SFTP)公开给调用者。

2 个答案:

答案 0 :(得分:2)

你需要的只是polymorphism使用指向FileTransfer的指针,使do_something()~FileTransfer()析构函数虚函数(即你在基础对象指针上调用函数,并且该对象将根据其真实类调用正确的函数。

剩下的问题只是基于协议构建对象。正确的术语不是"包装"但是" factory" (设计模式)。这可以通过FileTransfer的静态成员函数来实现。

答案 1 :(得分:2)

只需使用基类指针即可轻松完成此处的所有操作。

FileTransfer* ft;
std::unique_ptr<FileTransfer> ft; // C++11

制作一个:

// should this really be an int?
FileTransfer* factory(int protocol) {
    if (protocol)
        return new FTP;
    else
        return new SFTP;
}

// in C++11 this should be
std::unique_ptr<FileTransfer> factory(int protocol);

做点什么:

ft->do_something();

做一件针对其中一件事的事情:

// this will die if ft is an SFTP
dynamic_cast<FTP*>(ft)->use_passive();

// but you could check it
if (FTP* ftp = dynamic_cast<FTP*>(ft)) {
    ftp->use_passive();
}

// or perhaps even better, make a default virtual that does nothing
virtual void FileTransfer::use_passive() { }

void FTP::use_passive() override { // whatever }

ft->use_passive();

删除:

// make sure FileTransfer::~FileTransfer() is virtual!!
delete ft;