【问题标题】:A vector in a struct - best approach? C++结构中的向量 - 最佳方法? C++
【发布时间】:2011-09-08 23:04:12
【问题描述】:

我试图在我的结构中包含一个向量。

这是我的结构:

struct Region 
{
    bool hasPoly;
    long size1; 
    long size2;
    long size3;
    long size4;
    long size5;
    long size6;
    //Mesh* meshRef; // the mesh with the polygons for this region
    long meshRef;
    std::vector<int> PVS;
} typedef Region;

这个声明中的向量是否有效,或者做一个指向向量的指针是否更有意义。在指向向量的指针的情况下,我是否需要分配一个新向量。我将如何做到这一点?

谢谢!

编辑:问题在于它最终导致指向 xmemory.h 的错误,该文件包含在 MSVC++ 平台中。

    void construct(pointer _Ptr, _Ty&& _Val)
        {   // construct object at _Ptr with value _Val
        ::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val)); // this is the line
         }

有趣的是,如果我将它分配在结构之外并且只是在我使用的函数中分配它,它就不会发生。有什么想法吗?

【问题讨论】:

  • 这是完全有效的。如果你想使用指针,是的,你必须在构造函数中分配向量。
  • 我不认为那里需要 typedef,因为您使用的是 C++。
  • @Satchmo:我在 MSVC++ Express 10 中没有收到该错误,代码与您定义的完全一样...
  • 这是一个运行时错误:访问冲突写入位置。非常奇怪,因为它仅在向量位于结构中时发生。如果我在实际函数中声明一个向量,效果很好。
  • @Beta:如果他编译正确,那么在构造函数中分配在语义上与非指针成员相同(堆分配部分除外)。而且他仍然必须实施“三巨头”、适当的 RAII 模式等。

标签: c++ vector struct


【解决方案1】:

这样做是完全有意义的,并且您在任何方面都不需要new,除非您真的想为一个单独的向量设置别名。此外,这里不需要任何 typedef 的东西。

【讨论】:

    【解决方案2】:

    这取决于你如何使用它。

    如果要在复制Region 结构体时复制向量和数据,则将其保留为非指针。

    如果您不想将其复制过来,那么您将需要某种指向向量的指针。

    如果你使用指向向量的指针,你应该非常小心分配/释放异常的安全性。如果您不能以异常安全的方式确定分配范围,那么您就有可能发生内存泄漏。

    几个选项是:

    • 确保分配向量的代码(并使用Region)也释放向量,并且本身是异常安全的。这将要求 Region 仅存在于该代码的范围内。
      您可以通过简单地在堆栈上分配向量并将其传递给Region 中的指针来做到这一点。然后确保您永远不会在该堆栈帧上方返回 Region 对象。
    • 您还可以在 Region 中使用某种智能指针 -> 向量。

    【讨论】:

    • 查看正在发生的问题的编辑。对不起。这个网站的新手:)
    【解决方案3】:

    矢量很好。请注意,如果您复制此结构,则向量将与它一起复制。因此,在具有特定性能限制的代码中,请像对待任何其他复制成本高的类型一样对待这个结构体。

    在生产代码中,有些人希望您使用 class 关键字而不是 struct 关键字来定义此类,因为 vector 成员使其非 POD。如果您是自己的风格指南的作者,则无需担心。

    typedef 写错了,写struct Region { stuff };

    【讨论】:

      【解决方案4】:

      不用typedef也可以这样写:

      struct Region 
      {
          bool hasPoly;
          long size1; 
          long size2;
          long size3;
          long size4;
          long size5;
          long size6;
          long meshRef;
          std::vector<int> PVS;
      }; // no typedef required
      

      回答您的问题:

      此声明中的向量是否有效

      是的。

      或者做一个指向向量的指针更有意义。

      不,可能不会。如果你这样做了,那么你将不得不为复制行为实现复制构造函数、赋值运算符和析构函数。您最终会得到相同的结果,但这将是额外的工作并且可能会引入错误。

      如果是指向向量的指针,是否需要分配一个新向量。我将如何做到这一点?

      您需要实现复制构造函数复制赋值运算符析构函数

      // Copy constructor
      Region(const Region & rhs) :
          hasPoly(rhs.hasPoly),
          // ... copy other members just like hasPoly above, except for PVS below:
          PVS(new std::vector<int>(*rhs.PVS))
      {
      }
      
      // Copy assignment operator
      Region & operator=(const Region & rhs)
      {
          if (this != &rhs)
          {
               hasPoly = rhs.hasPoly;
               // ... copy all fields like hasPoly above, except for PVS below:
      
               delete PVS;
              PVS = new std::vector<int>(*rhs.PVS);
          }
          return *this;
      }
      
      // Destructor
      Region::~Region()
      {
          delete PVS;
      }
      

      底线:您的代码很好。你不需要改变它。

      编辑:修复赋值运算符:检查与 this 的比较并返回 *this。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2017-01-29
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      相关资源
      最近更新 更多