我正在尝试实现多态队列。
这是我的审判:

QQueue <Request *> requests;

while(...)
    {
        QString line = QString::fromUtf8(client->readLine()).trimmed();

        if(...)){
            Request *request=new Request();
            request->tcpMessage=line.toUtf8();
            request->decodeFromTcpMessage(); //this initialize variables in request using tcpMessage
            if(request->requestType==REQUEST_LOGIN){
                LoginRequest loginRequest;
                request=&loginRequest;
                request->tcpMessage=line.toUtf8();
                request->decodeFromTcpMessage();
                requests.enqueue(request);
            }
            //Here pointers in "requests" do not point to objects I created above, and I noticed that their destructors are also called.
            LoginRequest *loginRequest2=dynamic_cast<LoginRequest *>(requests.dequeue());
            loginRequest2->decodeFromTcpMessage();
        }
    }

不幸的是,由于我在第二条评论中提到的原因,我无法使用此代码来使Polymorphic Queue工作。我想我需要使用智能指针,但是如何使用呢?
我愿意对代码进行任何改进或对多态队列进行新的实现。

谢谢。

最佳答案

您的来源中有2个问题:

  • 您通过Request *request=new Request();声明了内存,但后来的request=&loginRequest;分配(不再可以删除)放弃了它,
  • 当执行离开定义变量的{}块时,LoginRequest loginRequest;变量将被破坏,从而导致request
  • 中的指针悬空

    我建议删除Request *request=new Request();行,然后在if(...){块中,通过以下方式分配具体的LoginRequest对象:

    LoginRequest * loginRequest = new LoginRequest();
    / *填写请求* /
    request.enqueue(loginRequest);

    您可以通过以下方法来摆脱排队对象:在队列对象弹出后(处理后)手动删除它们,或者在队列中使用容器安全的智能指针(boost::shared_ptr很好,也许是QT也有其中之一, std::auto_ptr不是容器安全的)。

    PITFALL还请确保Request的析构函数是虚拟的,因为当基类中没有虚拟析构函数时,您无法通过指向其基类的指针删除对象(在这种情况下,c++可以使用派生类实例调用基类的析构函数,导致未定义的行为,例如内存泄漏或崩溃)

    09-06 11:53