template <class T>
class Node
{
public:
T m_data; // Data to be stored
Node<T>* m_next; // Pointer to the next element in the list
// Purpose: Default constructor
// Postconditions: next pointer set to NULL
// ---INLINE---
Node() : m_next(NULL) {}
// Purpose: Auxiliaty constructor, construct from parameters
// Postconditions: data and next pointer set to parameters
// ---INLINE---
Node(const T& x, Node<T>* p)
: m_data(x), m_next(p) {}
};
template <class T>
class LinkedList
{
public:
Node<T>* head; // Pointer to the head of the list
// Purpose: Default constructor
// Postconditions: head pointer set to NULL
// ---INLINE---
LinkedList() : head(NULL) {}
template<class T>
const LinkedList<T>& LinkedList<T>::operator =(const LinkedList<T>& rhs)
{
if(this != &rhs)
{
if(head != NULL)
{
clear();
}
head = NULL;
Node<T>* rhsptr = rhs.head;
Node<T>* copyptr = new Node<T>;
copyptr->m_data = rhs->m_data;
while(rhs->m_next != NULL)
{
rhsptr = rhsptr->m_next;
copyptr = new Node<T>;
copyptr = copyptr->m_next;
copyptr->m_data = rhsptr->m_data;
}
copyptr->m_next = NULL;
}
return(*this);
}
COPY OPERATOR
template<class T>
LinkedList<T>::LinkedList(const LinkedList<T>& rhs)
{
*this = rhs;
}
当我编译时,它说:
linkedlist.hpp:24:25:错误:' - &gt;'的基本操作数有非指针类型'const
链表”
copyptr-&gt; m_data = rhs-&gt; m_data; ^ linkedlist.hpp:25:13:错误:' - &gt;'的基本操作数有非指针类型'const
链表”
while(rhs-> m_next!= NULL)
我很困惑因为我将rhsptr声明为指针类型所以我应该可以使用 - &gt;正确?
另外,如果这种编码一般起作用,我很困惑。我们已经在课堂上教过复制操作符应该模仿初始化并调用=运算符,但我看到一些代码正好相反。它们的复制构造函数被编码,赋值操作符调用它。
编辑2:这段代码给出了段错误,但我看不到任何东西。对此方面的任何帮助表示赞赏。
答案 0 :(得分:0)
您的声明或 rhs (对于复制构造函数是正确的)将其声明为引用,因此,而不是&#34; - &gt;&#34;你应该使用一个简单的&#34;。&#34;你在哪里得到错误。
使用&#34;&amp;&#34;在函数的参数中,它在语义上不同于它作为解除引用运算符的使用(&#34; 操作地址&#34;),尽管在功能上,它们的行为方式大致相同:它们阻止编译器在调用函数时制作对象的副本。以下是每种呼叫类型的示例:
/* This requires a copy of the node for use by the function
* The copy is placed on the top of the stack, and ceases to exist
* once the function exits.
* The copy is made via your copy constructor */
void fooA(Node<int> N){}
/* This requires a copy of a pointer to your node. To access members,
* you use the -> operator */
void fooB(Node<int> * N){}
/* This implicitly requires a copy of a pointer to your node, but this
* happens without you manually doing a dereference */
void fooC(Node<int> &N){}
// Here we exemplify the call format
int main(void){
Node<int> N;
fooA(N);
fooB(&N);
fooC(N);
return 0;
}
(请注意,我只使用Node作为示例,c ++中所有类型都是这种情况)
实际上创建了引用的呼叫(你的&#34; &amp; rhs &#34;)以允许更简单的sintax(使用&#34;。&#34;调用函数,而不需要调用函数中的&#34;&amp;&#34;而不是指针语义(例如:&#34; * rhs&#34;)。
至于你的第二个问题,你可以实现operator =作为对拷贝构造函数的调用,反之亦然,或者独立地,虽然根据我的经验(和个人偏好),编写代码更典型作为复制构造函数,然后从您的运算符实现引用它。
编辑:我应该补充一点,如果它不清楚,那么做一个对象的副本通常比使用指针(或引用)更加昂贵 - 指针通常会大约为4或8个字节(32对64位系统),但即使是简单的对象也可以大得多(节点应该是8或16个字节,例如,不计算运行复制构造函数所花费的时间)。
答案 1 :(得分:0)
针对“编辑2”问题。这些代码行:
copyptr = new Node<T>;
copyptr = copyptr->m_next;
将创建m_next
值为NULL
的新节点,然后将copyptr
设置为该值。这导致copyptr
为NULL
,当您尝试使用它时会导致错误。
相反,您希望更新当前copyptr
的{{1}}值以指向新节点,然后将m_next
设置为该新节点。
对代码稍作修改应该这样做:
copyptr