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.
pto iterate original list,npto build new list.
List::List(const List& original) {
Node *p = original.head;
Node *np = NULL;
head = NULL;
while (p != NULL) {
Node *n = new Node(p->getData(), NULL);
if (np == NULL) {
head = n;
} else {
np->setNext(n);
}
p = p->getNext();
np = n;
}
}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& List::operator=(const List& original) {
if (&original == this) {
return *this;
}
if (head != NULL) {
delete head;
head = NULL;
}
// same as copy constructor body ----
Node *p = original.head;
Node *np = NULL;
while(p != NULL) {
Node *n = new Node(p->getData(), NULL);
if (np == NULL) {
head = n;
} else {
np->setNext(n);
}
p = p->getNext();
np = n;
}
// ----
return *this;
}Recap on destructor
List::~List() {
delete 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:
Fraction(int num, int denm);
int getNumerator();
int getDenominator();
void setNumerator(int num);
void setDenominator(int denm);
void print();
};
Fraction::Fraction(int num, int denm) {
numerator = num;
// should check that denm is not 0, but ignore for now
denominator = denm;
}
int Fraction::getNumerator() {
return numerator;
}
int Fraction::getDenominator() {
return denominator;
}
void Fraction::setNumerator(int num) {
numerator = num;
}
void Fraction::setDenominator(int denm) {
// should check that denm is not 0, but ignore for now
denominator = denm;
}
void Fraction::print() {
cout << numerator << "/" << denominator << endl;
}Define the operator overloads for the operation:
Fraction X(1,5);
Fraction Y(4,6);
...
___ = X * Y; // the first multiply operation
___ = X * 2; // the second multiply operationThe first operator is:
Fraction::Fraction operator*(Fraction& rhs) {
Fraction w(numerator * rhs.numerator, denominator * rhs.denominator);
return w;
}The second operator is:
Fraction::Fraction operator*(int x) {
Fraction w(x * rhs.numerator, denominator);
return w;
}Fall 2018 - Q7
The following is the definition/implementation of a class called Foo.
class Foo {
private:
int priv;
public:
Foo(int pv) { priv = pv; }
Foo(const Foo src) { priv = src.priv; }
Foo& operator=(Foo& rhs) {
priv = src.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; }
Foo(const Foo& src) { priv = src.priv; }
Foo& operator=(Foo& rhs) {
priv = src.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;
ListNode *next;
};
ListNode* head;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) {
ListNode *n = node->next;
node->key = n->key;
node->next = n->next;
delete n;
}