题
/** @file ListP.cpp
* ADT list - Pointer-based implementation. */
#include <iostream>
#include <cstddef> // for NULL
#include <new> // for bad_alloc
#include "ListP.h" // header file
using namespace std;
List::List() : size(0), head(NULL)
{
} // end default constructor
List::List(const List& aList) : size(aList.size)
{
if (aList.head == NULL)
head = NULL; // original list is empty
else
{ // copy first node
head = new ListNode;
head->item = aList.head->item;
// copy rest of list
ListNode *newPtr = head; // new pointer
// newPtr points to last node in new list
// origPtr points to nodes in original list
for (ListNode *origPtr = aList.head->next; origPtr != NULL; origPtr = origPtr->next)
{
newPtr->next = new ListNode;
newPtr = newPtr->next;
newPtr->item = origPtr->item;
} // end for
newPtr->next = NULL;
} // end if
} // end copy constructor
void List::copy(const List& aList)
{
List::List(aList);
} // end copy
我想创建一个方法调用,复制简单地调用拷贝构造函数。当我在主要目标列表中测试这种方法仍然是空的。我已经通过它加强所有的右线执行,但当拷贝构造函数返回似乎没有被保存。我觉得这事做与范围,但无法查明问题。下面是驱动器程序:
#include <iostream>
using namespace std;
#include "ListP.h"
int main ()
{
List aList;
ListItemType dataItem;
aList.insert(1, 9);
aList.insert(2, 4);
aList.insert(3, 1);
aList.insert(4, 2);
List bList;
bList.copy(aList);
bList.retrieve(1, dataItem);
cout << dataItem << endl;
cout << bList.getLength() << endl;
return 0;
}
解决方案
如果我明白你的问题,你不能做你正在尝试做的。
在你可以调用对象的任何其他方法,必须将对象完全构造(这里有个例外,我会回到这一点)。此外,一个对象只能被构造一次(*)。因此,你可以打电话给你复制方法时,对象将已经构建,你不能(也不应该)建立了第二遍。
的一个例外不能够调用一个方法是不完全构造的对象上(即,尚未返回的构造函数)是一个构造本身可以调用部分构造的对象的方法。所以,你可以调用从拷贝构造函数拷贝的方法,而不是相反。
也就是说,如果您的对象提供了优化的交换函数,存在可能会想的标准特技:
void List::copy(const List& aList)
{
List acopy(aList);
swap(*this, acopy);
}
这使得ALIST的副本,然后交换与该拷贝的对象的当前内容。 ACOPY之前,现在有你的列表中的内容将被妥善销毁时拷贝的回报。
最后,如果你要做到这一点,目前的建议实际上是调整了一点,写这种方式:
void List::copy(List aList)
{
swap(*this, aList);
}
在某些情况下,这可以是更有效的(并且决不是效率较低的)。
* - 你可以做奇怪的事情,并与放置新构造对象的两倍。但是没有充分的理由这样做,原因是多方面的,为什么不这样做。
其他提示
在你的驱动程序,您必须
List bList;
bList.copy(aList);
相反,调用与拷贝构造或者
List bList(aList);
或
List bList = aList;
...你的“复制”的方法寻找:一个构造函数创建一个新的实例。您的名单::复制方法调用拷贝构造函数,在栈上创建目录的新实例。然后它返回,并且新的实例了。
你可能想的,而不是“复制”的方法是什么定义一个赋值运算符,
List& List::operator=(const List& aList)
{
if (this != &aList)
{
// Do your copying here
}
return *this;
}
然后你的驱动可以说
List bList;
// ...Presumably manipulate bList in some other ways in-between...
bList = aList;
要来自相同类别的另一方法中调用赋值运算符,说
*this = aList;
或
operator=(aList);
我发现后者别扭。但是,如果你想获得一个指向成员函数指的是一个运营商明确的名称可以是必要的。
构造函数是特殊的,因为它们被称为仅当对象是未初始化。因此,你不能调用任何简单的功能,复制或以其他方式。 C ++需要这个,因为它有助于写代码打破少,当你增加新的功能。
也许你想要的是移动的拷贝构造函数的身体Copy()
和Copy()
调用List::List(List const&)
。
现在的问题是,如果这样的语法是那么容易,那么为什么做出copy
方法都:>(除非你是谁想要的复印件明确指出那些防守人之一 - 那么我提出,我就是其中之一太)。
您还可能有兴趣做一个副本(分配)的操作而不是:
List& List::operator=(const List& aList)
{
//
}
至于无法调用拷贝构造参阅 C ++ FAQ精简版上构造的。这线程也要求同样的问题。
由于无法从类显式调用构造函数是标准文档的C ++的一部分,但maaan,你不想看那个东西......然而, - )