4

我有一个存储类。这个类的成员经常被修改。每次修改成员时,我都想保存类的状态(克隆类实例并保存)。所以我想创建一个新类,它将保存这些状态。

例如:

假设我在文件 storage.h 中有一个 Storage 类

class Storage 
{
 public:
   Int m_cnt;
   <lots of other members...>

   StorageHistory m_his;
};

以及文件 storagehistory.h 中的 StorageHistory 类

class StorageHistory 
{
 public:
   std::vector<Storage> m_history_vec;
};

假设:

  1. StorageHistory类应保留在存储类中。原因是Storage类是可以在所有类/包中访问的主类。为了尽量减少代码中的变化,我希望 StorageHistoryStorageclass.
  2. StorageHistory不能是静态的或单例的,因为创建了多个实例Storage

问题:

  1. 无法编译此代码。storage.h 需要在 storagehistory.h 之前编译,反之亦然
  2. 如果StorageHistory不能在Storage课堂上存储,那么我要保留它吗?谁是这个类的所有者?

需要帮助定义这两个类之间的联系吗?

4

4 回答 4

1

添加到你的头文件

存储.h

class Storage;  //to declear the class before the include

#include "StorageHistory.h"

//continue with the old declearation 

class Storage{
   ....
}

存储历史.h

class StorageHistory;  //to declear the class before the include

#include "Storage.h"

//continue with the old declearation 

class StorageHistory{
   ....
}

记得在文件中首先包含警卫。

可以对所有类都这样做,以避免将来出现此类问题。

于 2013-05-21T06:22:13.307 回答
1

首先:不要公开数据成员,除非你定义了一个纯数据结构。那么:Int不是C++类型。

现在回答您的问题:您可以使用前向声明。由于StorageHistory直接在 in 中使用Storage,因此不能前向声明,Storage只能在 in 的模板数据成员(即 a std::vector)中使用StorageHistory,并且该模板不需要定义Storageif 仅声明为变量。只有在使用向量方法时才需要定义。

所以这里是解开的代码:

存储历史.h

#include <vector>
class Storage;
class StorageHistory 
{
  std::vector<Storage> m_history_vec;
public:
  /* method declarations */
};

存储.h

#include "StorageHistory.h"
class Storage 
{
  int m_cnt;
  /* <lots of other members...> */
  StorageHistory m_his;
public:
  /* method declarations */
};

存储.cpp

#include "Storage.h"
#include "StorageHistory.h" //not necessarily needed, because implicitly included, but thats a matter of coding style

/* ... Storage methods definitions ... */
void Storage::changeVar(/*...*/)
{
  m_his.push_back(*this);
  /* ... */
}

存储历史.cpp

#include "StorageHistory.h"
#include "Storage.h"

/* ... StorageHistory method definitions ... */
于 2013-05-21T06:23:15.273 回答
0

你本质上是在做memento设计模式。您当前的编译问题将随着前向声明而消失。但是为了更好的设计和实现,你可以看到thisthis

于 2013-05-21T06:22:31.887 回答
0

您需要使用前向声明才能使您的解决方案正常工作。最简单的方法是将这些类放在同一个头文件中(但可能会有所不同):

class StorageHistory; // *** Forward declaration ***

class Storage 
{
public:
    Int m_cnt;
    &lt;lots of other members...&gt;

    StorageHistory m_his; 
};

class StorageHistory 
{
public:
    std::vector<Storage> m_history_vec;
};

不过,我不喜欢你的解决方案。m_his 将包含一个存储类列表,所有这些都将包含一个存储类列表(虽然是空的)。

我会创建一个带有存储向量映射的单例,并使用包含 UID 的容器包装一个存储。

class StorageContainer
{
private:
    static int nextUID = 0;
    int uid;
    Storage data;

public:
    StorageContainer()
    {
        uid = nextUID++; // Watch out for concurrency problems
    }

    Storage & GetData()
    {
        return data;
    }
};

然后,您可以通过其 UID 访问存储的历史记录。

class StorageHistory
{
    // The usual singleton stuff

    private:
        std::unordered_map<int, std::vector<Storage>> history;

    public:
        std::vector<Storage> & operator[] (int uid)
        {
            auto iter = history.find(uid);
            if (iter == unordered_map::end)
            {
                std::vector<Storage> newHistory;
                history[uid] = newHistory;
            }
            return history[uid];
        }
};
于 2013-05-21T06:23:07.427 回答