我正在尝试为 C++ 实现 BigInt,但遇到了复制构造函数的问题。你可以看到我注释掉了复制构造函数的原始代码,它只是 *this = orig;
。但我发现你需要使用指针来代替它。然而,我不完全确定这是如何工作的,目前代码没有正确地制作复制构造函数。
-BigIntVector 是自定义 vector 类。与 STL vector 比较。
BigInt.h:
class BigInt {
private:
BigIntVector bigIntVector;
bool isPositive;
int base;
unsigned int skip;
BigIntVector* ptr; //pointer to copy?
public:
// copy constructor
BigInt(BigInt const& orig);
// constructor where data value is passed as a long
BigInt(long num);
// destructor
~BigInt();
// binary '+' operator
BigInt operator+(BigInt const& other) const;
// unary '+' operator
BigInt operator+() const;
//more operator unloading functions
这是我当前在 BigInt.cpp 中实现的构造函数:
// copy constructor
BigInt::BigInt(BigInt const& orig) {
ptr = new BigIntVector;
*ptr = *orig.ptr;
//*this = orig;
}
// constructor where operand is a long
BigInt::BigInt(long num) {
//this->data = num;
ptr = new BigIntVector;
base = 10;
int sizeOfLong = 0; //holds size of num
int tempNum = num;
//get size of num
if (tempNum == 0) {
sizeOfLong = 1;
}
while (tempNum != 0)
{
tempNum /= 10;
++sizeOfLong;
}
//resize vector to match size of long
bigIntVector = BigIntVector(sizeOfLong);
if (num < 0) {
isPositive = false;
num *= -1;
}
else {
isPositive = true;
}
long pushedNum;
//cout << "num: " << num << endl;
for (int i = sizeOfLong - 1; i >= 0; --i) {
pushedNum = (long)(num%base);
bigIntVector.setElementAt(i, pushedNum);
num /= base;
}
}
// destructor
BigInt::~BigInt() {
//delete *this;
}
//code for overloading operators for BigInt below
BigIntVector 构造函数的代码:
BigIntVector::BigIntVector(long initialSize)
{
vectorTotalSize = initialSize;
vectorIncrementSize = initialSize;
vectorArray = (long *)malloc(initialSize*sizeof(long));
for (long i = 0; i < initialSize; i++) vectorArray[i] = 0;
nextValue = 0;
}
最佳答案
在现实世界中(家庭作业之外),BigInt
类不应该需要显式复制构造函数。内存分配应该委托(delegate)给一个单独的类——很可能是 std::vector
。如果您需要一个指针作为类成员(在这种情况下不太可能),使用 std::shared_ptr
管理它就不需要复制构造函数。
这是我之前的一篇文章,旨在解决您对在 C++ 中使用 new
的误解。该描述中对 C# 的引用同样适用于 Java:Is garbage collection automatic in standard C++?
关于评论中的一个问题:“正式成员的语法是什么”。建议的评论只是说不要将元素声明为指针(只需省略 *
)。总结一下,对于这个类:
- 你不需要指针
- 你不需要拷贝构造函数
- 你不需要使用
new
关键字
在这种情况下,问题出在您的 BigIntVector
类中。因为那是分配内存和管理指针的那一个,所以那是需要复制构造函数的那一个。如果这是家庭作业,我建议申请 rule of three到您的 BigIntVector
实现。您将需要所有以下内容:
- 复制构造函数,复制内存
- 一个赋值运算符,它也复制内存
- 一个释放内存的析构函数
如果不是作业,我建议用 std::vector
替换 BigIntVector
。
为非平凡类声明复制构造函数是个坏主意,因为您通常需要显式复制每个成员(或者它们将被默认初始化而不是复制)——最好让编译器来做为您避免错误。
如果你必须为这个作业做一个,正确的形式应该是这样的:
BigInt::BigInt(BigInt const& orig)
: bigIntVector(orig.bigIntVector)
, isPositive(orig.isPositive)
, base(orig.base)
, skip(orig.skip)
{
// empty body
}
将算术运算符转发到复合赋值运算符的规范形式是以下的一些变体:
T& T::operator += ( T const & b )
{
...class-specific math logic that modifies the object...
return (*this);
}
T operator + ( T const & a, T const & b )
{
T temp(a); // create a temporary copy of 'a' rather than modifying it
return temp += b;
}
关于c++ - BigInt C++ 和正确的复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33558602/