我想在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)公开给调用者。
答案 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;