假设我有两个BitArrays,每个都有分配成员来存储实际位。
我想实现按位或,和。
我的尝试:
BitArray BitArray::operator &(const BitArray &other) const
{
BitArray anded;
anded.Initialize(this->m_Size);
for (uint32 i = 0 ; i < this->m_Size; i++)
{
anded.m_Array[i] = other.m_Array[i] & m_Array[i];
}
return anded;
}
在从被调用的函数析构函数返回之前,我的所有作业都将丢失,此外,对已分配对象的析构函数的后续调用将会崩溃。
我有哪些选择?创建BitArray的子类作为MoveableBitArray,并重载复制构造函数来移动数据?还有其他选择吗?感谢。
我不使用C ++ 11。
编辑:现在我在课堂上没有复制构造函数。
答案 0 :(得分:2)
编辑:现在我在课堂上没有复制构造函数。
嗯,那是你的问题。无论如何,您对编译器的期望是什么?您返回了本地的副本,但没有告诉它做任何特别的事情。你当然没有告诉它不要破坏你的本地,然后再复制。它完全按照你的要求去做。你创造的每一个变量,都会为你摧毁,正如圣标所说的那样。当你要求它复制你的返回值时,它就完全按照预期的方式完成了这一点。你没有要求它在这里做任何特别的事。
如果要返回本地变量的副本,并且需要特殊的复制行为,则实现复制构造函数。这就是它的用途。编译器可能应该如何实现返回局部变量,如果它不能移动它,因为它是C ++之前的11并且它不能复制,因为它是如此昂贵?编译器应该做什么?
编辑:我实际上并没有非常关注你的代码,但在我看来你重新实现了boost :: dynamic_bitset,但更糟糕的是,在你的实现中,你重新实现了std :: vector但是更糟糕的是。这些标准和半标准类存在是有原因的,你只是重复他们的努力。只需使用它们就会更容易,更快。答案 1 :(得分:0)
如果将实例传递给函数或通过值从函数返回实例,则必须在该实例的类中实现复制构造函数:
构造函数+析构函数:
BitArray::BitArray()
{
Allocate(0);
}
BitArray::~BitArray()
{
DeallocateAll();
}
BitArray::BitArray(const BitArray& cBitArray)
{
Allocate(0);
*this = cBitArray;
}
作业运营商:
const BitArray& BitArray::operator=(const BitArray& cBitArray)
{
if (this == &cBitArray)
return *this;
DeallocateAll();
Allocate(cBitArray.m_Size);
for (unsigned int i=0; i<m_Size; i++)
m_Array[i] = cBitArray.m_Array[i];
return *this;
}
const BitArray& BitArray::operator&=(const BitArray& cBitArray)
{
return *this = *this & cBitArray;
}
二元运营商:
BitArray operator&(const BitArray& cBitArray1,const BitArray& cBitArray2)
{
if (cBitArray2.m_Size < cBitArray1.m_Size)
return cBitArray2 & cBitArray1;
BitArray cRes;
cRes.Allocate(cBitArray2.m_Size);
unsigned int i;
for (i=0; i<cBitArray1.m_Size; i++)
cRes.m_Array[i] = cBitArray1.m_Array[i] & cBitArray2.m_Array[i];
for (; i<cBitArray2.m_Size; i++)
cRes.m_Array[i] = cBitArray2.m_Array[i];
return cRes;
}
内部例行程序:
void BitArray::Allocate(unsigned int size)
{
m_Size = size;
if (m_Size > 0)
m_Array = new unsigned char[m_Size];
}
void BitArray::DeallocateAll()
{
if (m_Size > 0)
delete[] m_Array;
m_Size = 0;
}