Lecture 28 - Nov 16, 2023
Summary
In this lecture, we continue our discussion on inheritance, data protection within a derived classes and pointers to derived classes.
Last lecture
Inheritance.
Today
Inheritance continuation.
We inherit the attributes from Person
.
We do not inherit constructors.
If we create a new setName()
, it will overwrite the previous one.
In Person.h
:
#include <iostream>
using namespace std;
class Person {
private:
;
string nameint age;
public:
() {
Person= "";
name = 0;
age }
(string n, int a) {
Person= n;
name = a;
age }
void setName(string n) { name = n; }
void print() {
<< "Name: " << name << endl;
cout << "Age: " << age << endl;
cout }
};
In Student.h
:
#include <iostream>
using namespace std;
class Student : public Person {
private:
int ID;
// age and name are innaccessible
// we don't inherit constructors of Person
public:
() { ID = 0; }
Student
// setName is inherited
void setNameID(string n, int d = 0) {
::setName(n);
Person= d;
ID }
// cancel/overwrite the print function inherited from Person
// we write our own
void print() {
// I can't access age and name
::print();
Person<< "ID: " << ID << endl;
cout }
~Student() { cout << "Student destructor" << endl; }
};
In main.cpp
:
#include "Person.h"
#include "Student.h"
using namespace std;
int main() {
("Joe", 23);
Person p; // 2 constructors are called
Student s// 1st is Person() default constructor
// 2nd is Student() default constructor
.setName("Joseph");
p.print(); // print name and age
p
.setNameID("Ryan"); // setNameID is inherited from Person
s.print(); // we invoke print on Student object, hence we call print of
s// Student, not of person
.setNameID("Marina", 125);
s.print();
s
return 0;
}
Inheritance versus membership
Inheritance
Inheritance represents an “is-a” relationship.
Example: Student
is a Person
, as Student
inherits from Person
.
class Person {
...
};
class Student : public Person {
...
};
;
Student s.SetName();
s
// s is Student
// s is Person
Membership
Membership represents a “has-a” relationship.
Example: Student
has a member Person
p
.
class Student {
private:
;
Person p};
;
Student s
// s is Student
// s is NOT person
Access different constructors
What if I want to call a different Person
constructor when I create a Student
object?
class Student : public Person {
private:
int ID;
public:
() { ID = 0; }
Student// or
// Student() : ID(0);
// call the 2nd constructor in Person
// between fun() and {, the space allows an initializer's list
(string n, int a, int d) : Person(n,a) {
Student= d;
ID }
};
int main() {
// 1. Person(n,a)
// 2. Student(n,a,d)
("Armaan", 20, 354);
Student s}
Data protection
protected
data and function members are inherited and accessible to derived classes but not to all classes (somewhere between public
and private
).
class Person {
protected:
int age;
;
string name};
class Student : public Person {
private:
int ID;
public:
(string n, int a, int d) {
Student::name = n;
Person::age = a;
Person= d;
ID }
};
Important. We do not inherit
- Constructors: You can call them.
- Copy constructors
- Operator equal
- Destructors
2-4: You can create derived’s own version of them.
int main() {
;
Student s;
Person p
= s; // => p.operator=(s)
p // Person& operator=(Person& rhs) { ... }
= p; // => s.operator=(p) - LHS is student, RHS is person => ERROR
s }
Very important. student
is a Person
and Student
. person
is a Person
only.
* s1;
Student* p1;
Person
= &s; p1
p1
pointer can be used to access Person
members which also exist in Student
s
.
->setName("Selim"); // calls setName of Person
p1->print(); // calls print of Person
p1// p1->setNameID(); // error, because setNameID is not a member of Person
s1
pointer cannot access all Student
members as not all of them exist in Person
(base class).
// s1 = &p; // error