Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设计一个围绕多个功能的优秀C++包装类 我想设计一个C++类的包装类,它使用FTP、sftp、_C++_Oop_Design Patterns_Wrapper - Fatal编程技术网

设计一个围绕多个功能的优秀C++包装类 我想设计一个C++类的包装类,它使用FTP、sftp、

设计一个围绕多个功能的优秀C++包装类 我想设计一个C++类的包装类,它使用FTP、sftp、,c++,oop,design-patterns,wrapper,C++,Oop,Design Patterns,Wrapper,我有一个使用curl的基类FileTransfer,它由派生类FTP继承。我需要支持SFTP,所以我实现了另一个派生类SFTP,它也继承自FileTransfer 我将按照下面的思路编写一个包装类代码。然而,这看起来不是一个好的设计。我对OOP比较陌生,虽然我以前在C上工作过 类包装器{ 公众: Wrapperint m_协议{ 协议=m_协议; if协议 pftp=新FTP; 其他的 psftp=新的SFTP; } ~z~包装纸{ if协议 删除pftp; 其他的 删除psftp; } //

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

我将按照下面的思路编写一个包装类代码。然而,这看起来不是一个好的设计。我对OOP比较陌生,虽然我以前在C上工作过

类包装器{ 公众: Wrapperint m_协议{ 协议=m_协议; if协议 pftp=新FTP; 其他的 psftp=新的SFTP; } ~z~包装纸{ if协议 删除pftp; 其他的 删除psftp; } //ftp/sftp都支持的功能 做点什么{ if协议 pftp->做点什么; 其他的 psftp->做点什么; } //FTP特定功能 无效使用{ 资产协议; pftp->使用被动; } //特定功能 无效ssh_密钥{ 断言协议; psftp->ssh_密钥; } 私人: int协议; FTP*pftp; SFTP*psftp; }; 您只需使用指向FileTransfer的指针,使do_有事,并使用~FileTransfer析构函数虚拟函数,即在基本对象指针上调用函数,对象将根据其实际类调用正确的函数


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

这里的一切都可以通过使用基类指针轻松完成

FileTransfer* ft;
std::unique_ptr<FileTransfer> ft; // C++11
做某件特定于某一方的事情:

// 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();

你为什么用包装纸?你需要包装纸吗?似乎在大多数情况下,您可以使用文件传输*,即FTP*或SFTP*。绝对不是两个指针,也绝对不是void*。我使用的是包装器,因为在项目中的很多地方,都在使用现有的FTP对象,如果我为SFTP使用一个单独的类而没有包装器,我每次都必须添加一个if检查来支持SFTP。我想让调用方不知道它是FTP还是SFTP。@MukulGupta更好的设计方向可能是使用facade或mixin接口聚合IMHO。谢谢。在FileTransfer中使用虚拟成员函数更有意义。使用dynamic_cast,调用方必须重复创建指向FTP/SFTP的指针。让我们假设,与其返回void use_passive,还不如返回int int{},这会导致错误FileTransfer::use_passive必须返回一个值。我不能让它成为一个纯粹的虚拟函数,因为那样会使类抽象,我还必须在SFTP类中实现use_passive。可以采取什么措施来防止这种情况?
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;