【问题标题】:Cloning vector of pointers指针的克隆向量
【发布时间】:2016-06-05 16:35:01
【问题描述】:

您好,我是新来的,也是 C++ 的新手。我有一个问题,我需要制作我的指针向量的备份副本。但我不能正确地得到它。我在这个论坛上找到了我的案例的解决方案,但无法正确解决:

class cloneFunctor {
public:
    T* operator() (T* a) {
        return a->clone();
    }
}

我试图在我的代码中实现这一点,但无法很好地解决,谁能帮我解决这个问题?

我的代码:

服务器.cpp

  #include "server.h"
    #include <iostream>
    #include <functional>
    #include <algorithm>
    #include <iterator>
    class Client;


    class cloneFunctor {
    public:
        cloneFunctor* operator() (cloneFunctor* a) {
            return a->clone();
        }
    };

    Server *Server::instance = 0;

    Server& Server::getInstance() {
        if (instance == 0)
            instance = new Server();
        return (*instance);
    }

    void Server::setStatus(bool status) {
        this->nStatus = status;
        changeClientStatus();
        writeStateToConsole();
    }

    bool Server::getStatus() {
        return nStatus;
    }

    void Server::writeStateToConsole() {
        std::cout << "Server state: " << getStatus() << std::endl;
    }

    void Server::subscribeToServer(Client &temp) {
        listOfClients.push_back(&temp);
    }
    void Server::writeClients() {
        for (unsigned int i = 0; i < listOfClients.size(); i++) {
            std::cout << i+1  << ". client status: " << listOfClients[i]->getStatus() << std::endl;
        }
    }

    void Server::changeClientStatus() {
        if (nStatus == 0){
            makeCopy(listOfClients);
            for (unsigned int i = 0; i < listOfClients.size(); i++) {
                listOfClients[i]->setStatus(false);
            }
        }
        else
            restoreCopy();

    }

    void Server::makeCopy(std::vector<Client *>listOfClients) {
         transform(listOfClients.begin(), listOfClients.end(), back_inserter(listOfClientsOld), cloneFunctor());
    }
    void Server::restoreCopy() {


    }

服务器.h

#ifndef SERVER_H_
#define SERVER_H_

#include "abstractbaseclass.h"
#include "server.h"
#include "client.h"



class Client;
class Server : public Abstractbaseclass {
    friend class Client;
public:
    static Server& getInstance();
    virtual void setStatus(bool status);
    virtual bool getStatus();
    virtual void writeStateToConsole();
    void subscribeToServer(Client &temp);
    void writeClients();
    void changeClientStatus();
    void makeCopy(std::vector<Client *>listOfClients);
    void restoreCopy();


 private:
    static Server *instance;
    Server(){};
    std::vector <Client *>listOfClients;
    std:: vector <Client *> listOfClientsOld;
};


#endif /* SERVER_H_ */

程序应该创建单例服务器类,然后创建 3 个将订阅服务器的客户端(这些客户端保存在指针向量中)。当我将服务器状态设置为 0 时,所有客户端都将其状态更改为关闭(bool false)并且在这之前应该创建备份向量,因为当我再次打开服务器时,客户端需要从关闭服务器之前切换到它们的状态。

【问题讨论】:

  • 如果在服务器未运行时未修改客户端,您将做很多额外的工作。从概念上讲,最好不要保留向量的副本,而是让Clients 负责备份和恢复自己。这使服务器变得非常愚蠢,并使服务器更难通过复制或替换客户端的状态来任意搞砸它。
  • 这其实不是我的主意怎么解决,这是我们老师想要的,所以我必须处理它,并且“实现他的愿望”

标签: c++ vector clone


【解决方案1】:

好的,所以他正在尝试教授某种基于交易的思维方式。

Client 可能需要赋值运算符

Client & operator=(Client & toCopy)
{
    // copy all of toCopy's members over to this
}

如果它还没有一个并且包含指针或复杂的数据类型,您不能相信它们可以自我复制。

现在你可以轻松

clientA = clientB;

clientB 复制到clientA

然后我们进入主要事件Server::restoreCopy(),这是一个非常简单的变体:

if (listOfClients.size() != listOfClientsOld.size())
{
    // back up is stale. Probably throw exception
}
for (size_t index = 0; index < listOfClients.size(); index++)
{
    *listOfClients[index] = *listOfClientsOld[index];
}

这些是 vectors 的指针,因此您必须取消引用 (*) 指针以获取指向 Client 的指针,或者复制指针而不是指向的指针。请记住,Client 的克隆是完全不同的Client 而不是Server 的用户首先传入的内容。如果Server 用户仍然持有最初的Client 并使用它,那么如果你只复制指针就会发生错误的ju-ju。双方将在不同的Clients 上运行,即使它们看起来相同。一次修改就不会了

您也可以使用std::transform 技巧在此处进行备份,但这简单明了且易于调试。随意使用迭代器和基于范围的for

当您使用它时,请祈祷自从您进行备份以来没有人重新订购listOfClients

重要的旁注:

void makeCopy(std::vector<Client *>listOfClients);

很奇怪。它允许Server 用户传入他们自己的vector 并添加到任何现有的备份中。这包括Server 本身。它不会删除任何现有备份,因此listOfClientsOld 将继续增长。而且因为任何有权访问Server 的人都可以调用它并传入他们自己的vector,所以他们可以将其填充为充满谬误的废话。我建议 makeCopy 不带参数并从备份中删除任何现有的 Clientsdelete 它们。更好的是,listOfClientsOld 根本不需要存储指针,可能也不应该。

很多指针在玩,没有deletes。必须有人归还您分配的所有内存,否则您最终会用完。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    相关资源
    最近更新 更多