32
Chapter 11 Friends and Overloaded Operators

Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Embed Size (px)

Citation preview

Page 1: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Chapter 11

Friends and Overloaded Operators

Page 2: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Introduction to function equal// Date.h#ifndef _DATE_H_#define _DATE_H_

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate& aDay); // copying constructor~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int year;private:

int month;int day;

};#endif

#include “Date.h”

bool equal (CDate day1, CDate day2);void main (){

CDate myBD(3, 31, 1996), yourBD;cout << "Enter your birthday as month, day, year ”; int m, d;cin >> m >> d >> yourBD.year;yourBD.setMonth(m);yourBD.setDay(d);if (equal(myBD, yourBD))

cout << “Let’s celebrate together.”; }

bool equal (CDate day1, CDate day2){

return (day1.getMonth() == day2.getMonth()) &&day1. getDay() == day2. getDay()) &&day1.year == day2.year);

}

Page 3: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Function equal

• prototype of equal is outside of the class.• equal is a nonmember function of the class

requiring 2 objects• To access the members, it must still use member

accessor functions since the attributes are private and can only be accessed by public member functions.

• It does not change the data members. Only member functions or friend functions should be able to alter private members.

Page 4: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Friend functions• A non-member function that has membership

privileges.• Notes:

– Prototype goes in public section with keyword friend in front

– Function call is like a regular function - does not use dot operator

– When to use:• Functions between two members of the same class

Page 5: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Friend function equal// Date.h#ifndef _DATE_H_#define _DATE_H_

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate& aDay); // copying constructor~CDate(); // destructor

friend bool equal(CDate day1, CDate day2);int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int year;private:

int month;int day;

};#endif

#include “Date.h”

void main (){

CDate myBD(3, 31, 1996), yourBD;cout << "Enter your birthday as month, day, year ”; int m, d;cin >> m >> d >> yourBD.year;yourBD.setMonth(m);yourBD.setDay(d);if (equal(myBD, yourBD))

cout << “Let’s celebrate together.”; }

bool equal (CDate day1, CDate day2){

return (day1.month == day2.month) &&day1. day == day2. day) &&day1.year == day2.year);

}

Page 6: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

The const Parameter Modifier• It is more efficient to call by reference than by value.

– value: passes in a copy of the variable. If the variable is large or structured this takes up extra space.

– reference: passes in the address only but it does allow changes

• Solution: call by reference but put const modifier which prevents change - generates error message.

• Used for classes, structs and arrays. • const used after function prototype and definition prevents

function from changing calling objects - generates error message. – void output (ostream& outs) const;

• If the function prototype and it’s definition do not both have the const modifier, then you will get a linkage error.

• Accessor and output functions should be const.

Page 7: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Friend function equal with const// Date.h#ifndef _DATE_H_#define _DATE_H_

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate& aDay); // copying constructor~CDate(); // destructor

friend bool equal(const CDate& day1, const CDate& day2);int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int year;private:

int month;int day;

};#endif

#include “Date.h”

void main (){

CDate myBD(3, 31, 1996), yourBD;cout << "Enter your birthday as month, day, year ”; int m, d;cin >> m >> d >> yourBD.year;yourBD.setMonth(m);yourBD.setDay(d);if (equal(myBD, yourBD))

cout << “Let’s celebrate together.”; }

bool equal (const CDate& day1, const CDate& day2){

return (day1.month == day2.month) &&day1. day == day2. day) &&day1.year == day2.year);

}

Page 8: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloading Operator

• Changing the definition of an operator from the default operation to a new operation.

• Allows for smooth functionality in ADT’s.

Page 9: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloading Operator (example)

• Want to write as:if (myBD == yourBD) // syntax error

• Current operation == does not take operands typed CDate.

• Need to redefine == operator to take 2 CDate objects.

• Function definition is exactly the same as equal.• Declared as a friend function.• Has the keyword operator.

Page 10: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Friend function equal with const// Date.h#ifndef _DATE_H_#define _DATE_H_

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate& aDay); // copying constructor~CDate(); // destructor

friend bool operator ==(const CDate& day1, const CDate& day2);int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int year;private:

int month;int day;

};#endif

#include “Date.h”

void main (){

CDate myBD(3, 31, 1996), yourBD;cout << "Enter your birthday as month, day, year ”; int m, d;cin >> m >> d >> yourBD.year;yourBD.setMonth(m);yourBD.setDay(d);if (myBD == yourBD)

cout << “Let’s celebrate together.”; }

bool operator ==(const CDate& day1, const CDate& day2){

return (day1.month == day2.month) &&day1. day == day2. day) &&day1.year == day2.year);

}

Page 11: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Rules for Overloading Operators• At least one argument must be of the class type.• Overloaded operators can be friends or member

functions.• Can only overload existing operators• Can’t change the number of arguments from the

original operator (binary (+), unary (++))• Can’t change precedence rules• Can’t overload dot operator(.), scope resolution

operator (::).• Overloading the assignment operator is a special

case.

Page 12: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloading Unary Operators

• Has only 1 object in the parameter list:– Negate: -– Increment: ++– Decrement: --

Page 13: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloading >> and <<

• The compiler does not automatically know how to output or input user-defined classes.

• Need to specify how each attribute is to be entered.

• Want input to be user friendly.– Ex: cin >> yourBD; // as format mm-dd-yyyy

• Want output to be clear and in standard form.– Ex: cout << yourBD; // as format mm/dd/yyyy

Page 14: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Arrays and Classes

• An array can be of any type.• Composite types (struct or class) can be

stored in arrays.• Ex:

CDate studentBDs[25];int n=5;if (studentBDs[n] == myBD)if (studentBDs[n].year < 1998)if (studentBDs[n].getMonth() == 3)

Page 15: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Arrays as Class Member

• Any composite type can contain an array.• Ex

class CStudentInfo{

…char name;SDate bDay;float quiz[5];

};CStudentInfo students[25], myBestStudent;myBestStudent.quiz[0] = 10;students[2].quiz[0] = 8;

Page 16: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Class CComplex definition//Complex.h#ifndef _COMPLEX_#define _COMPLEX_

#include <iostream>using namespace std;class CComplex{public:

CComplex(void);CComplex(double, double);CComplex(const CComplex&);~CComplex();

// Unary operator to negate the values of a complex number:// -(r, i) = (-r, -i)friend CComplex operator - (const CComplex& c);

// operator to add 2 complex numbers: // (r1, i1) + (r2, i2) = (r1+r2, i1+i2)friend CComplex operator + (const CComplex& left, const CComplex& right);

// operator to subtract 2 complex numbers:// (r1, i1) - (r2, i2) = (r1-r2, i1-i2)friend CComplex operator - (const CComplex& left, const CComplex& right);

// operator to multiply 2 complex numbers:// (r1, i1)(r2, i2) = (r1r2-i1i2, i1r2+r1i2)friend CComplex operator * (const CComplex& left, const CComplex& right);

// operator to compare if 2 complex numbers are the samefriend bool operator == (const CComplex& left, const CComplex& right);

// extraction operator to get input for real, imaginaryfriend istream& operator >> (istream& ins, CComplex& c);

// insertion operator to display a complex number as (a + bi)// where a is real and b is imagfriend ostream& operator << (ostream& outs, const CComplex& c);

private:

double real;double imag;

};#endif

Page 17: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Class CComplex implementationCComplex::CComplex(void) : real(0), imag(0){}CComplex::CComplex(double r, double i) : real(r), imag(i){}CComplex::CComplex(const CComplex& c) real(c.real), imag(c.imag){}CComplex::~CComplex() {}

CComplex operator - (const CComplex& c){

CComplex temp;temp.real = -c.real;temp.imag = -c..imag;return temp;

}CComplex operator + (const CComplex& left, const CComplex& right){

CComplex temp;temp.real = left.real + right.real;temp.imag = left.imag + right.imag;return temp;

}CComplex operator - (const CComplex& left, const CComplex& right){

CComplex temp;temp.real = left.real - right.real;temp.imag = left.imag - right.imag;return temp;

}

CComplex operator * (const CComplex& left, const CComplex& right){

CComplex temp;temp.real = left.real*right.real - left.imag*right.imag;temp.imag = left.imag*right.real + left.real*right.imag;return temp;

}bool operator == (const CComplex& left, const CComplex& right){

return (left.real == right.real) && (left.imag == right.imag);}

istream& operator >> (istream& ins, CComplex& c){

ins >> c.real >> c.imag;return ins;

}ostream& operator << (ostream& outs, const CComplex& c){

outs.setf(ios::fixed);outs.setf(ios::showpoint);outs.precision(2);

outs << '(' << c.real << ", ";if (c.imag > 0.0) outs << '+';outs << c.imag << “i)”;return outs;

}

Page 18: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Class CComplex implementation (used parameterized constructor)

CComplex::CComplex(void) : real(0), imag(0){}CComplex::CComplex(double r, double i) : real(r), imag(i){}CComplex::CComplex(const CComplex& c) real(c.real), imag(c.imag){}CComplex::~CComplex() {}

CComplex operator - (const CComplex& c){

return CComplex(-c.real, -c.imag);}

CComplex operator + (const CComplex& left, const CComplex& right){

return CComplex((left.real + right.real), (left.imag + right.imag));}

CComplex operator - (const CComplex& left, const CComplex& right){

return CComplex(left.real - right.real, left.imag - right.imag);}

CComplex operator * (const CComplex& left, const CComplex& right){

return CComplex((left.real*right.real - left.imag*right.imag), (left.imag*right.real + left.real*right.imag));

}

bool operator == (const CComplex& left, const CComplex& right){

return (left.real == right.real) && (left.imag == right.imag);}

istream& operator >> (istream& ins, CComplex& c){

ins >> c.real >> c.imag;return ins;

}

ostream& operator << (ostream& outs, const CComplex& c){

outs.setf(ios::fixed);outs.setf(ios::showpoint);outs.precision(2);

outs << '(' << c.real << ", ";if (c.imag > 0.0) outs << '+';outs << c.imag << “i)”;return outs;

}

Page 19: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Class with pointer data members#include "Date.h"CDate::Date () : month(1), day(1), year(new int(1900)){}CDate::Date (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~Date () {}

int CDate::getMonth(){

return month;}int CDate::getMonth(){

return month;}int CDate::getDay(){ return day;}void CDate::setMonth(int m){ month = m;}….

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructor~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int *year;private:

int month;int day;

};

Page 20: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Destructor

• Every class needs to tell the compiler how to destroy the object and return the memory to the freestore.

• Destructor is used to destroy a class object and return the memory to the heap. – In the case of standard variables, it will automatically return the

memory to the heap and the destructor is empty.– In the case of dynamic variables, it will destroy the pointer but not

return the memory to the heap unless we use the delete command.• With dynamic variables, only the pointer would be deleted and not what

it points to.• Need to write the destructor specifically and use delete.

• Automatically called when scope ends

Page 21: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Destructor (example)class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructor~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int *year;private:

int month;int day;

};

#include "Date.h"CDate::Date () : month(1), day(1), year(new int(1900)){}CDate::Date (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~Date () {

cout <<“Bye-bye: ”<<month<<“-”<<day<<“-”<<*year<<endl;}…

#include "Date.h“void main () {

CDate myBD (1, 1, 1990);CDate yourBD (12, 31, 2000);

}

Bye-bye: 12-31-2000Bye-bye: 1-1-1990

Output:

So, what happens to the memory location reserved for year? Still occupied

Page 22: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Destructor (example)class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructor~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int *year;private:

int month;int day;

};

#include "Date.h"CDate::Date () : month(1), day(1), year(new int(1900)){}CDate::Date (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~Date () {

cout <<“Bye-bye: ”<<month<<“-”<<day<<“-”<<*year<<endl;delete year;

}…

#include "Date.h“void main () {

CDate myBD (1, 1, 1990);CDate yourBD (12, 31, 2000);

}

Bye-bye: 12-31-2000Bye-bye: 1-1-1990

Output:

So, what happens to the memory address reserved for year? Freed

Page 23: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Copy Constructor• Creates a copy of an object in a different memory location. • Parameter list has one variable that is an object of the class.• The parameter is preceded by const and is a call by reference.

– Ex: CDate (const CDate& d);

• Called automatically whenever a function has a parameter of the class type.– Ex: CDate myBD(yourBD);

• Any classes using pointers and new operator (dynamic variables) should have a copy constructor. Otherwise, the compiler will only copy the pointers so they both have the same address (both point to the same memory address, rather than each point to the same data but in different addresses. This is called a “shallow copy”).

Page 24: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Copy Constructor (example)#include "Date.h“

CDate::CDate () : month(1), day(1), year(new int(1900)){}CDate::CDate (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~CDate () {

delete year;}

CDate::CDate (const CDate& d) : month(d.month), day(d.day), year(d.year){}

CDate::~CDate () {delete year;

} …

class CDate{public: CDate(); // default constructor CDate(int m, int d, int y); // parameterized constructor CDate(const CDate&); // copy constructor ~CDate(); // destructor

int getMonth(); // accessor int getDay(); // accessor void setMonth(int m); // mutator void setDay(int d); // mutator

void display(); // a member function

int *year;private: int month; int day;};

Page 25: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Copy Constructor (const.)#include "Date.h“void main () {

CDate myBD (1, 1, 1990);{ CDate yourBD (myBD); }cout << “My birth year is: ” << myBD.year << endl;

}

What happens to the memory address reserved for myBD’s year?

Destroyed by yourBD’s destructor

Output: ??? -17891602 (garbage)

Why garbage???

myBD’syear

yourBD’syear

1900

myBD’syear

yourBD’syear

?

Both myBD’s year and yourBD’s year point to the same memory address.When one is destroyed, the other becomes dangling pointer.

10,000

Page 26: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Copy Constructor (example)class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate&); // copy constructor~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member function

int *year;private:

int month;int day;

};

#include "Date.h"CDate::CDate () : month(1), day(1), year(new int(1900)){}CDate::CDate (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~CDate () {

delete year;}CDate::CDate (const CDate& d) : month(d.month), day(d.day){

year = new int;*year = *(d.year);

}CDate::~CDate () {

delete year;} …

Page 27: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Copy Constructor (const.)#include "Date.h“void main () {

CDate myBD (1, 1, 1990);{ CDate yourBD (myBD); }cout << “My birth year is: ” << myBD.year << endl;

}

What happens to the memory address reserved for myBD’s year?

Still there and used by myBD’s year

Output: ??? 1990

Why exception NOT raised???

myBD’syear

yourBD’syear

1900

myBD’syear

yourBD’syear

?

Both myBD’s year points to a different memory address, not related to the address of yourBD’s year.

10,000 190011,000

190010,000

Page 28: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloading the Assignment Operator

• If NOT overloaded, the compiler will create one and that assignment operator will copy all the values of data members of the assigner (on the right) to the corresponding ones of the assignee (on the left).

• The “shallow copy” will happen if a data member is a pointer. So, the assignment operator needs to be overloaded to assign the pointer to another memory address.

void CDate::operator = (const CDate& d)

{

month = d.month;

day = d.day;

year = d.year;

}

Page 29: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Assignment Operator not overloaded

#include "Date.h“void main () {

CDate myBD (1, 1, 1990);{CDate yourBD = myBD; }cout << “My birth year is: ” << myBD.year << endl;

}

What happens to the memory address reserved for myBD’s year?

Destroyed by yourBD’s destructor

Output: ??? -17891602 (garbage)

Why garbage???

Both myBD’s year and yourBD’s year point to the same memory address.When one is destroyed, the other becomes dangling pointer.

myBD’syear

yourBD’syear

1900

myBD’syear

yourBD’syear

?

10,000

Page 30: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloaded Assignment Operator (example)

class CDate{public:

CDate(); // default constructorCDate(int m, int d, int y); // parameterized constructorCDate(const CDate&); // copy constructors~CDate(); // destructor

int getMonth(); // accessorint getDay(); // accessorvoid setMonth(int m); // mutatorvoid setDay(int d); // mutator

void display(); // a member functionvoid operator = (const CDate& d); // Assignment op.int *year;

private:int month;int day;

};

#include "Date.h"CDate::CDate () : month(1), day(1), year(new int(1900)){}CDate::CDate (int m, int d, int y) : month(1), day(1), year(new int(y)){}CDate::~CDate () {

delete year;}CDate::CDate (const CDate& d) : month(d.month), day(d.day){

year = new int;*year = *(d.year);

}CDate::~CDate () {

delete year;} void CDate::operator = (const CDate& d){

month = d.month;day = d.day;year = new int;*year = *(d.year);

}…

Page 31: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

Overloaded Assignment Operator (const.)

#include "Date.h“void main () {

CDate myBD (1, 1, 1990);{ CDate yourBD (myBD); }cout << “My birth year is: ” << myBD.year << endl;

}

What happens to the memory address reserved for myBD’s year?

Still there and used by myBD’s year

Output: ??? 1990

Why exception NOT raised???

myBD’syear

yourBD’syear

1900

myBD’syear

yourBD’syear

?

Both myBD’s year points to a different memory address, not related to the address of yourBD’s year.

10,000 190011,000

190010,000

Page 32: Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();

The Big Three

• Copy constructor, assignment operator and destructor are the big three of a class.

• Rule that if you need to define one of them, you need to define all of them or the compiler will create them but they might not work correctly!