我想在C ++中编写一个简单灵活的ftp服务器,可以通过类来参数化来处理服务器初始化时提供的用户(检查登录名和密码,提供文件等)。
所以我提出了这个整洁(我想的)想法:
class FtpDelegate
{
public:
FtpDelegate() {}
virtual ~FtpDelegate() {}
virtual bool login(QString username, QString password) = 0;
// ...
};
class DummyDelegate : public FtpDelegate
{
public:
virtual bool login(QString username, QString password)
{
return true;
}
};
template<class Delegate>
class FtpServer : public QObject, Derived_from<Delegate, FtpDelegate>
{
Q_OBJECT
public:
explicit FtpServer(const QHostAddress &address = QHostAddress::Any,
quint16 port = 21,
QObject *parent = 0);
public slots:
void newConnection();
private:
QTcpServer *server;
QHostAddress address;
};
template <class Delegate>
void FtpServer<Delegate>::newConnection()
{
FtpDelegate *delegate = new Delegate();
new FtpConnection (delegate, server->nextPendingConnection(), address, this);
}
class FtpConnection : public QObject
{
Q_OBJECT
public:
explicit FtpConnection(FtpDelegate *delegate,
QTcpSocket *socket,
const QHostAddress &address,
QObject *parent = 0);
public slots:
void newDataConnection();
private:
QTcpSocket *socket;
QTcpServer *dataServer; // needed to transfer data to user
QTcpSocket *dataSocket;
};
// server initialization
FtpServer<DummyDelegate> ftpServer();
然后(你可能看到即将到来)bam!
Error: Template classes not supported by Q_OBJECT
可能还有其他错误或误解,因为我只是开始学习C ++模板机制(以及Qt)。
我的问题是:在不使用丑陋黑客的情况下使其工作的最佳方法是什么,例如传递函数指针或需要为每个具体的FtpDelegate派生类创建工厂实现。也许有一些我看不到的聪明的设计模式。最终,如果它是最佳选择,我可以重写网络机制来提升。
答案 0 :(得分:2)
无法创建模板Q_OBJECT类(请参阅this和答案)。
您应该使用运行时继承,并注入一个继承自FtpDelegate类的对象,而不是使用静态继承。
看起来FtpServer实际上是一个创建连接的工厂。从你的问题,我不明白为什么它必须是Q_OBJECT类。因此,您可能需要重新考虑您的设计,并简化该课程。
什么是使其工作的最佳方法,而不使用丑陋的黑客,如传递函数指针或需要为每个具体的FtpDelegate派生类创建工厂实现。
最好的方法是拥有一个工厂类,它会创建FtpDelegate
类型的实例。但是你在发布的代码中遇到了很多问题,如果不知道所有的血腥细节,就不可能说出更多。