我想写一些我正在编写的库的单元测试
我有一个看起来像这样的课程:
class A
{
public:
A(B* pB)
// construction details, involves my library
// but ultimately there is a new being done ,)
B* m_pB;
};
我想检查指针m_pB是否实际初始化,所以我沿着这些方向做了一些事情:
A* p = // creation of this object involves my library
BOOST_REQUIRE( p->m_pB != NULL );
但它发生了g ++没有对内存进行零初始化,因此p->m_pB
的值只是随机的。当我new
对象时,有没有办法迫使g ++为我初始化这个内存为零?
我相信Visual Studio会根据内存的分配位置执行与特定代码类似的操作。
编辑:我现在可以想到2个备份解决方案:使用智能指针或编写新的运算符......
答案 0 :(得分:9)
只需实现默认构造函数即可。这保证了在不传递参数的情况下,指针被初始化为NULL。
class A
{
public:
A(B* pB)
// construction details, involves my library
// but ultimately there is a new being done ,)
A() : m_pB(NULL) {}
B* m_pB;
};
或者Fritschy指出:
A() : m_pB() {}
答案 1 :(得分:6)
使用始终初始化的类。
template<typename T> class always_initialized {
T t;
public:
operator T&() { return t; }
operator const T&() const { return t; }
always_initialized() : t() {}
always_initialized(const T& ref) : t(ref) {}
};
编辑:我看到大多数人都不明白这实际上是做什么的。如果您只是将指针设置为NULL,那么您必须在每个构造函数中单独执行此操作,然后您必须为每个变量再次执行此操作,并且它对于POD结构等其他POD事物也不通用。 always_initialized
更易于维护,因为它不会重复您自己,更简洁,更通用,因为它对任何POD类型甚至非POD类型都有好处。
答案 2 :(得分:3)
您是否考虑过将m_pB
设为私有并始终在构造函数中初始化它?通过使用封装来强制执行类不变量,您甚至不需要来执行您在此处实现的各种检查。
答案 3 :(得分:-2)
感谢您的回答,但我想要一种侵入性较小的技术,因为这些类是测试的一部分,并且它们的构造函数正好位于主题的中间位置,即依赖注入。
我只是跳过类似于visual studio的东西,它在调试模式下将内存设置为某个特定值(我认为?),通过g ++或类似的选项。
一些答案/评论基本上回归说“不要测试它,只是不要犯错”
最后,我重载了新运营商并添加了对memset(ptr, 0, size);
的调用
我得到了critical check p->m_pB != __null failed
,它运作正常。