Lecture 21 - Oct 24, 2023
Summary
In this lecture, we discuss copy constructor and operator= of linked lists. We also review the material for the midterm.
Today
Copy constructor, operator=
, and midterm revision.
Recap on copy constructor
Creates an object from an existing one.
The default copy constructor does a shallow copy.
We need to do a deep copy:
- Copy one node at a time.
p
to iterate original list,np
to build new list.
::List(const List& original) {
List*p = original.head;
Node *np = NULL;
Node = NULL;
head
while (p != NULL) {
*n = new Node(p->getData(), NULL);
Node
if (np == NULL) {
= n;
head } else {
->setNext(n);
np}
= p->getNext();
p = n;
np }
}
Recap on operator equals
The idea is similar to the copy constructor, except that the lhs may not be empty. We must empty lhs first.
& List::operator=(const List& original) {
Listif (&original == this) {
return *this;
}
if (head != NULL) {
delete head;
= NULL;
head }
// same as copy constructor body ----
*p = original.head;
Node *np = NULL;
Node
while(p != NULL) {
*n = new Node(p->getData(), NULL);
Node
if (np == NULL) {
= n;
head } else {
->setNext(n);
np}
= p->getNext();
p = n;
np }
// ----
return *this;
}
Recap on destructor
::~List() {
Listdelete head;
}
Past exam questions
Fall 2019 - Q14
The following class is used to create objects that represent ordinary fractions n/d
, consisting of a numerator n
and a denominator d
.
#include <iostream>
using namespace std;
class Fraction {
private:
int numerator;
int denominator;
public:
(int num, int denm);
Fractionint getNumerator();
int getDenominator();
void setNumerator(int num);
void setDenominator(int denm);
void print();
};
::Fraction(int num, int denm) {
Fraction= num;
numerator
// should check that denm is not 0, but ignore for now
= denm;
denominator }
int Fraction::getNumerator() {
return numerator;
}
int Fraction::getDenominator() {
return denominator;
}
void Fraction::setNumerator(int num) {
= num;
numerator }
void Fraction::setDenominator(int denm) {
// should check that denm is not 0, but ignore for now
= denm;
denominator }
void Fraction::print() {
<< numerator << "/" << denominator << endl;
cout }
Define the operator overloads for the operation:
(1,5);
Fraction X(4,6);
Fraction Y...
= X * Y; // the first multiply operation
___ = X * 2; // the second multiply operation ___
The first operator is:
::Fraction operator*(Fraction& rhs) {
Fraction(numerator * rhs.numerator, denominator * rhs.denominator);
Fraction wreturn w;
}
The second operator is:
::Fraction operator*(int x) {
Fraction(x * rhs.numerator, denominator);
Fraction wreturn w;
}
Fall 2018 - Q7
The following is the definition/implementation of a class called Foo
.
class Foo {
private:
int priv;
public:
(int pv) { priv = pv; }
Foo
(const Foo src) { priv = src.priv; }
Foo
& operator=(Foo& rhs) {
Foo= src.priv;
priv return this;
}
int getPriv() { return priv; }
void setPriv(int pv) { priv = pv; }
};
Compiling the above definition/implementation results in one or more errors. Re-write the class so it is error-free. Write your answer (the entire definition/implementation).
The code requires the following corrections:
// Foo(const Foo src) { priv = src.priv; }
(const Foo& src) { priv = src.priv; }
Foo
& operator=(Foo& rhs) {
Foo= src.priv;
priv // return this;
return *this;
}
I cannot return a local variable by reference.
Fall 2021 Final - Q7
It is desired to implement an efficient deletion function in a linked list. You are given a linked list pointed to by head
and a pointer node
to a node in a linked list, which is guaranteed not to be the last node in the list (i.e., not the tail node). Write a function removeNode
that removed this node from the list. You should not iterathe the nodes in the list.
You may assume the following is the definition of the class, ListNode
. The head node of the linked list is pointed to by head
.
class ListNode {
public:
int key;
*next;
ListNode };
* head; ListNode
You are not allowed to change the function’s argument or return type.
void removeNode(ListNode *node) {
...
}
The solution is to copy the data from the next node into the current node, and then delete the next node.
void removeNode(ListNode *node) {
*n = node->next;
ListNode ->key = n->key;
node->next = n->next;
nodedelete n;
}