c++ - BigInt C++ 和正确的复制构造函数?

标签 c++ pointers constructor copy-constructor biginteger

我正在尝试为 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/

相关文章:

c - C 中的不可变结构值

java - 提供编写构造函数的帮助

c++ - 如何在头文件之外定义构造函数?

c++ - 如何知道两个对象是否派生自同一个基类?

c++ - 64位减法结果转32位整数

c - *p 和 (*p)[3] 在函数中有什么区别?

当本地磁盘上不存在文件时,java文件构造函数

c++ - 我应该使用哪个 TLS 库,可移植性是个问题

c++ - 在 C++ 中使用排序谓词

c - 指针的内存分配