如何公开常量数据

时间:2014-12-19 08:30:54

标签: c++ unit-testing oop

我正在编写单元测试用例,为此我编写了一些结构及其数组,用于保存输入数据并校正结果。数据就像这样

.e.g测试总和(a,b)返回a,b我有以下代码

struct Data
{
   const int a,b,c;  
};

Data arr[] = 
{
    {1,0,1};
    (2,1,3};
}

const unsigned int getsizeofarr()
{
    return sizeof(arr)/sizeof(arr[0]);
}

我不确定这是否是以OOPS术语公开数据的最佳方式。我已经使变量const,但const_cast可以轻松删除它并修改数据。让我知道如何公开我的测试数据,使其保持常量并且也可以被测试用例访问。

提前致谢

3 个答案:

答案 0 :(得分:1)

你可以创建这样的访问器方法:

class Data
{
public:
  inline int GetA() const { return a; }
  inline int GetB() const { return b; }
  inline int GetC() const { return c; }
private:
  const int a, b, c;
};

访问者方法是不会改变对象状态的方法。它们只是用于通过提供额外的访问层来控制对象内数据访问的方法。这样,用户将无法直接访问,并且必须通过访问器方法来访问原始数据。

为避免const_cast改变只读数据,最简单的方法是隐藏数据的内存位置,这意味着用户必须既无法获取引用也无法获取指向数据的指针。这实际上意味着您只需向用户提供数据副本。

从您的示例来看,您似乎只使用int,因此返回副本通常很便宜。但是,假设您的vector为1000000 int。试图复制它将是相当昂贵的(只考虑如何制作1000000 int s数组的副本。在这种情况下,数据的大小并不重要,您可能希望将只读引用返回给数据,以防止任何类似的复制。

class Data
{
public:
  inline const std::array<int, 1000>& GetA() const { return a; }
  inline const std::array<int, 1000>& GetB() const { return b; }
  inline const std::array<int, 1000>& GetC() const { return c; }
private:
  const std::array<int, 1000> a, b, c;
};

所以最后,你必须做出判断。数据安全性比性能更重要吗?如果是,则隐藏数据并仅返回数据的副本。否则,数据是否可以忽略不计?如果是这样,返回引用might actually be more expensive而不是简单地复制数据,否则返回只读引用。

伪代码:

If security is more important than performance
  Return a copy
Otherwise
  If size of data is of negligible size
    Return a copy
  Otherwise
    Return a read-only reference

答案 1 :(得分:0)

  

我不确定这是否是以OOPS术语公开数据的最佳方式。我已经使变量const,但const_cast可以轻松删除它并修改数据。让我知道如何公开我的测试数据,使其保持常量并且也可以被测试用例访问。

const_cast不是用于从数据中删除const,因此您可以对其进行修改;那是UB。当您需要调用未标记为const的API(但不会修改数据)时,它应该用于从数据中删除const说明符。

那就是说,考虑让客户端代码决定什么应该是const。这将允许您更灵活地使用Data实例并在使用时指定constness(更明确)。

代码:

struct Data
{
   int a,b,c; // no const here
};

const std::array<Data, 2> arr = {
    {1,0,1};
    (2,1,3};
}; // const here

另请注意:考虑至少使用std :: array:它提供了比原始数组类型更好的接口和安全性。

答案 2 :(得分:0)

通常,您不会将结构的成员标记为常量,而是变量,您可以定义:

struct Data { 
    int a,b,c; 
}; 

const Data arr[] = { {1,0,1}, {2,1,3} };

正如其他人已经提到的,你肯定应该用std :: vector或std :: array替换c风格的数组(这样你也可以摆脱getsizeofarr)。