【问题标题】:Linked lists | Overloading + operator | C++链表 |重载 + 运算符 | C++
【发布时间】:2012-03-23 12:57:40
【问题描述】:

我正在训练我的 C++,我正在尝试编写一个库,该库将能够使用链表表示以下数字:

999999999 * ( [i=0]Σ[999999999] 1000000000 ^ i )

例如,如果我的号码是 711381450277869054011,它会这样表示:

711 * 1000000000^2 + 381450277 * 1000000000^1 + 869054011 > * 1000000000^0

所以,这里是我的 LL 的结构和它的功能:

typedef struct node* ll;
struct node
{
    unsigned int data;
    ll next;
};

bool insert(ll&, unsigned int);
// ...
void copy(ll&, ll);
void destroy(ll&);

这是我的无符号超长整数类:

class uli
{
public:
    uli();
    ~uli();

    // <<, >>, =, operators...

    uli& operator +=(const uli&);
    uli& operator +=(char*);
    const uli operator +(const uli&);

private:
    ll head;
};

uli::uli()
{
    head = NULL;

    insert(head, 0);
}

uli::~uli()
{
    destroy(head);
}

+= 运算符工作正常,我正在使用它来重载 + 运算符。

问题是我不能让 operator+() 方法返回一个 const uli 而不会在我使用它之前被解构器破坏。

const uli uli::operator +(const uli& rarg) // rarg: right argument
{
    uli larg; // left argument

    larg = *this;

    larg += rarg;

    return larg;
}
// returns an LL to somewhere ???? larg was destroyed.

现在我不能Z = X + Y;

【问题讨论】:

  • 你实现了复制构造函数吗?
  • 不,我没有。这很关键吗?
  • @jonas:是的。如果您不创建一个,那么编译器必须创建一个,因为这就是从函数返回的工作方式。并且编译器的版本只是复制对象的内容——包括head指针——而不是做任何类型的深拷贝。
  • 我明白了。这就是它不能暂时保存返回的 uli 的原因吗?

标签: c++ linked-list overloading operator-keyword


【解决方案1】:

您需要关注Rule of Three

如果你的班级需要任何一个

  • 复制构造函数,
  • 赋值运算符,
  • 或析构函数,

那么很可能需要这三个。

问题的根本原因:
在您的情况下,当您通过从重载的operator + 复制返回类uli 实例时,将使用编译器生成的隐式复制构造函数,它会生成指针的浅拷贝,因此多个指针指向相同的内存地址,当一个/其中一些(临时对象)被破坏,指向的内存通过析构函数被释放,剩下的指针(悬空)指向不存在的内存/内容。

解决方案:
遵循三法则并实现您自己的复制构造函数来执行涉及的指针的Deep Copying

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2013-11-17
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多