gpt4 book ai didi

C++ - 从抽象基指针调用派生函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:13:29 24 4
gpt4 key购买 nike

我一直在尝试创建基于继承的 TCP 服务器模型,并取得了不同程度的成功。这些服务器由一个单例管理,其任务是关闭这些服务器和其他简单的维护功能:

class TCPServer {
public:
TCPServer();
~TCPServer();

void Bind(TCPDaemon *daemon) {
if(!daemon->IsRunning()) {
throw TCPBindException("Daemon is inactive");
}

// if the port is not taken, bind this daemon to it
if(this->servers.count(daemon->port())==0) {
this->servers[daemon->port()]=daemon;
...
} else {
throw TCPBindException("Port is taken");
}
}

void Shutdown() {
MASON::UINT16 i;
for(i=0;i<this->servers.size();i++) {
this->Shutdown((*this->servers.begin()).first);
}
}

void Shutdown(unsigned short port) {
if(this->servers.count(port)) {

if(this->servers[port]->IsRunning()) {
this->servers[port]->Stop();
}

delete this->servers[port];
this->servers.erase(port);

}
}

private:
std::map<unsigned short, TCPDaemon*> servers;

};

TCPDaemon 类的 Stop() 函数是纯虚拟的。我的问题是,当调用 Shutdown() 函数时,它试图调用这个纯虚拟而不是派生类的版本。我怎样才能强制它做正确的事情?

提前致谢

[edit] 抱歉,我之前没有包含 TCPDaemon 代码,它派生自 TCPSocket 类(我已经检查过该类 100% 正常工作并且相当不言自明)。在这里:

class TCPDaemon: public TCPSocket {
public:
TCPDaemon(unsigned short port) {
this->_enabled=false;
this->_host.ipaddr(INADDR_ANY);
this->_host.port(port);
this->paused=false;

struct sockaddr_in opts=this->_host.Compile();

#ifdef PLATFORM_WINDOWS
WSADATA wsaData;
if(WSAStartup(0x0202, &wsaData)) {
throw TCPDaemonException("Failed to start WSA");
}
#endif

this->raw_socket=socket(AF_INET, SOCK_STREAM, 0);
if(this->raw_socket<=0) {
throw TCPDaemonException("Failed to create socket");
}

if(int status=bind(this->raw_socket, (sockaddr*)&opts, sizeof(sockaddr))) {
printf("error [%i]\r\n", status);
throw TCPDaemonException("Failed to bind to port");
}

if(listen(this->raw_socket, 5)) {
throw TCPDaemonException("Failed to listen on port");
}

this->_enabled=true;

}

virtual ~TCPDaemon() {
this->Shutdown();
}

virtual void Start()=0;
virtual void Run(TCPSocket*)=0;
virtual void Stop()=0;

unsigned short port() {
return this->host().port();
}

bool IsRunning() {
return this->_enabled;
}

TCPSocket *Accept() {
SOCKET client;
struct sockaddr client_addr;
int len=sizeof(client_addr);
client=accept(this->raw_socket, &client_addr, &len);

return new TCPSocket(client, &client_addr);
}

void Shutdown() {

}

private:
bool _enabled;
bool paused;

};

这是一个示例派生服务器及其创建方法:

   class EchoServer: public TCPDaemon {
public:
EchoServer(MASON::UINT16 port): TCPDaemon(port) {
}

~EchoServer() {}

virtual void Start() {

}

virtual void Run(TCPSocket *client) {
printf("RUN\r\n");
Accessor<TCPSocket> acc_client=client;
acc_client->Write(Accessor<Blob> (new Blob(std::string("hello!"))));
acc_client->Disconnect();
}

virtual void Stop() {

}

};

myTCPServer->Bind(new EchoServer(8008));

[edit+1] 我认为问题归结为这个(我很可能是错的):我有一个基类 TCPDaemon 的 std::map,它有一个纯虚拟/抽象函数 Stop()。看起来,当我通过映射中的一个条目调用 Stop() 时,它试图调用 TCPDaemon::Stop(),而不是覆盖函数 EchoServer::Stop()。这可能是问题所在吗?如果是,我该如何解决?

最佳答案

检查你声明的语法:

class TCPDaemon
{
virtual void stop() = 0;
};

class MyDaemon : public TCPDaemon
{
virtual void stop()
{
//Do stuff here.
}
};

这是我在没有更多代码的情况下所能做的最好的事情。

编辑:

好的,看来您正在使用抽象函数。下一个问题是:你得到的错误是什么?我可以肯定地说,它不是试图从 TCPDeamon 调用 Stop()。那是不可能的,因为它甚至没有实现。

关于C++ - 从抽象基指针调用派生函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3526275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com