我正在进行一项测试,检查是否在构造函数中初始化了所有类属性。 我当前的解决方案适用于非指针属性:
void CSplitVectorTest::TestConstructorInitialization()
{
const size_t memorySize = sizeof(CSplitVector);
char* pBuffer1 = (char*) malloc(memorySize);
char* pBuffer2 = (char*) malloc(memorySize);
memset(pBuffer1,'?',memorySize);
memset(pBuffer2,'-',memorySize);
new(pBuffer1) CSplitVector;
new(pBuffer2) CSplitVector;
const bool bObjectsAreEqual = memcmp(pBuffer1,pBuffer2,memorySize)==0;
if (!TEST(bObjectsAreEqual))
{
COMMENT("Constructor initialization list not complete!");
}
free(pBuffer1);
free(pBuffer2);
}
您是否知道如何测试指针是否已初始化?
答案 0 :(得分:0)
您的测试检查构造函数是否已写入对象的每个字节。作为直接内存检查,它看起来没问题,但如果该类包含其他不必完全初始化的对象,则可能会遇到麻烦。
那就是说,我的主要问题是:它真的是一个有效的测试吗?例如,CSplitVector
类中的每个属性是否都由初始化列表初始化是至关重要的?你或许有一些可能不需要在这一点初始化?另外,如何检查属性是否设置为您期望的值?
答案 1 :(得分:0)
您可能应该使用正确的填充或字大小,而不是逐字节进行比较,并测试每个字的任何字节是否已初始化。这样你就可以使用填充和构造函数绕过编译器,在填充的短于字的字段之间留下未初始化的字节。
为了测试真正的填充大小,从臀部拍摄,下面的代码应该非常可靠地完成:
struct PaddingTest {
volatile char c; // volatile probably not needed, but will not hurt either
volatile int i;
static int getCharPadding() {
PaddingTest *t = new PaddingTest;
int diff = (int)(&(t->i)) - (int)&((t->c));
delete t;
return diff;
}
}
编辑:您仍然需要这两个对象,但是您不再将它们与其他对象进行比较,您只需将每个初始化数据与memset值进行比较,如果任一对象有任何更改,则表示该单词被触摸(同样在另一个,它只是被初始化为你设置的相同值的机会。
答案 2 :(得分:0)
我找到了上述问题的解决方案,使用初始化/未初始化的指针和不同长度类型对其进行了测试。
在测试标题中,我添加了#pragma pack(1)(我正在使用gcc)
#pragma pack(1)
#include <CSplitVector>
测试有点复杂:
void CSplitVectorTest::TestConstructorInitialization()
{
const size_t memorySize = sizeof(CSplitVector);
char* pBuffer = (char*) malloc(memorySize);
memset(pBuffer,'?',memorySize);
CSplitVector* pSplitVector = new(pBuffer) CSplitVector;
// find pointers for all '?'
QList<char*> aFound;
char* pFoundChar = (char*) memchr(pBuffer,'?',memorySize);
while (pFoundChar)
{
aFound.append(pFoundChar);
char* pStartFrom = pFoundChar+1;
pFoundChar = (char*) memchr(pStartFrom,'?',memorySize-(int)(pStartFrom-pBuffer));
}
// if there are any '?'....
if (aFound.count())
{
// allocate the same area with '-'...
pSplitVector->~CSplitVector();
memset(pBuffer,'-',memorySize);
pSplitVector = new(pBuffer) CSplitVector;
// and check if places found before contain '-'
while (aFound.count())
{
pFoundChar = aFound.takeFirst();
if (*pFoundChar=='-')
{
// if yes then class has uninitialized attribute
TEST_FAILED("Constructor initialization list not complete!");
pSplitVector->~CSplitVector();
free(pBuffer);
return;
}
}
}
// if no then all attributes are initialized
pSplitVector->~CSplitVector();
free(pBuffer);
TEST(true);
}
随意指出此解决方案中的任何缺陷。