Friend Functions and Classes in C++

 
CMSC202
 Computer Science II for Majors
Lecture 13 –
Friends and More
 
Dr. Katherine Gibson
 
Last Class We Covered
 
Linked Lists
Traversal
Creation
Insertion
Deletion
 
 
2
 
Any Questions from Last Time?
 
 
Today’s Objectives
 
To cover some miscellaneous topics:
Friends
Destructors
Freeing memory in a structure
Copy Constructors
Assignment Operators
 
4
 
Friend Functions and Classes
 
Why Have Friends?
 
Giving direct access to private variables is not
possible if the function is not a class method
 
But using accessors can be cumbersome,
especially for something like an overloaded
insertion operator (
<<
)
 
Use a “friend” function to give direct access,
even though the function is not called on an
object of that class
6
Friend Functions
 
Non-member functions that have
member-style access
 
Function is declared 
inside
 the class
Will be public regardless of specifier
 
Designate using the 
friend
 keyword
friend void
 
aFriendFunction
();
 
 
 
7
Friend Classes
 
Classes can also be declared to be friends of
another class
 
class
 
Milo 
{
public
:
  
friend class 
Otis
;
};
 
class 
Otis
 { ... };
8
the Otis class now
has access to all of
the private members
of the Milo class
Forward Declarations
 
When one class references another in its
definition, we need a 
forward declaration
Tell the compiler it exists, without defining it
 
In order to reference the 
Otis
 class before
it’s defined, we need something similar:
 
class 
Otis
;
before the 
Milo
 class declaration
 
9
Using Friends
 
Why give access to private member variables?
 
Useful for testing functionality
Increased speed
Operator overloading
Enhances encapsulation
A function being a friend is specified 
in
 the class
10
 
Destructors
 
Destructors
 
Destructors
 are the opposite of constructors
 
Used when 
delete() 
is called on an
instance of a user-created class
 
Compiler automatically provides one for you
Does not take into account dynamic memory
If your class uses dynamic memory, you must write
a better destructor to prevent memory leaks!
12
Destructor Example: Date
 
Let’s say we have a new member variable of
our 
Date
 class called ‘
m_next_holiday
Pointer to a string with name of the next holiday
 
class 
Date
 {
private
:
  
int     
m_month
;
  
int     
m_day
;
  
int     
m_year
;
  
string 
*
m_next_holiday
 ;
};
 
13
Destructor Example: Date
 
We will need to update the constructor
 
Date
::
Date 
(
int 
m
, 
int 
d
, 
int 
y
,
            
string 
next_holiday
) {
  SetMonth(m);
  SetDay(d);
  SetYear(y);
  m_next_holiday  = new string;
  *m_next_holiday = next_holiday;
}
 
 
14
What other changes do we need to
make to a class when adding a new
member variable?
Creating a Destructor
 
We also now need to create a destructor of
our own:
 
~Date();    
// our destructor
 
Destructors must have a tilde at the front
Similar to a constructor:
Destructor has no return type
Same name as the class
15
Basic Destructor Definition
 
The destructor needs to free 
all
 of the
dynamically allocated memory
Otherwise we will have 
memory leaks
 
Most basic version of a destructor
 
Date
::~
Date
() {
  
delete
 m_next_holiday;
}
16
 
Security and Carefulness
 
Date
::~
Date
() {
  
delete
 m_next_holiday;
}
 
This works, but it isn’t very secure for the data,
and it isn’t very careful with our pointers
What if someone gets access to this memory later?
What if my code tries to access m_next_holiday
after it’s been deleted?
 
17
Ideal Destructor Definition
 
Clears 
all
 information and sets pointers to 
NULL
 
Date
::~
Date
() {
   // clear member variable info
   m_day = m_month = m_year = 0;
   *m_next_holiday = 
""
;
   // free and set pointers to NULL
   delete
 m_next_holiday;
   m_next_holiday = NULL;
}
18
Why aren’t we
using the mutator
functions here?
Freeing Memory
 
Done using the 
delete()
 function
Takes a pointer as an argument:
 
delete
(grades);
 
delete
(letters);
 
delete() 
does not work recursively
For each individual allocation, there 
must
 be an
individual call to free that allocated memory
Called in a 
sensible
 order
 
19
 
Freeing in Order
 
In what order would you free the
nodes of this linked list?
 
20
 
Freeing in Order
 
In what order would you free the
nodes of this binary tree?
 
21
 
Copy Constructors and
Assignment Operators
 
Copying Objects…
 
When does C++ make copies of objects?
Pass by value
Return by value
Assignment
and…
New object initialized from existing object
 
Copy Constructor
 
Initialize an object based on an existing object
Examples:
int a = 7;
int b(a);
 
// Copy constructor
 
Shoe shoeOfMJ( “Nike”, 16 );
Shoe myShoe( shoeOfMJ );
 
// Copy
 
Copy Constructor
 
Use when dynamic memory is allocated
Syntax:
Prototype:
ClassName( const ClassName& obj );
Implementation:
ClassName::ClassName( const ClassName& obj )
{
// code to dynamically allocate data
}
 
Why do we care?
 
Remember
Assignment (by default) makes a direct copy of
data members…
With dynamic memory – this would be copying
pointers
Class
-------------
int *data1
string *data2
Object *data3
7
abc
Foo
bar
Class
-------------
int *data1
string *data2
Object *data3
 
What do we want?
 
Each object should have own memory
allocated to members…
Class
-------------
int *data1
string *data2
Object *data3
7
abc
Foo
bar
Class
-------------
int *data1
string *data2
Object *data3
7
abc
Foo
bar
Example
class Shoe
{
public:
Shoe( const Shoe& shoe );
private:
int *m_size;
string *m_brand;
};
Shoe::Shoe( const Shoe& shoe )
{
m_size = new int( *shoe.m_size );
m_brand = new string( *shoe.m_brand );
}
 
What’s going on here?
 
What else?
 
Assignment Operator
Define if using dynamic memory
Syntax:
Prototype:
ClassName& operator=( const ClassName& obj );
Definition:
ClassName& ClassName::operator=( const ClassName& obj )
{
// Deallocate existing memory, if necessary
// Allocate new memory
}
What’s Wrong With This?
Shoe& Shoe::operator=(
   
const Shoe& shoe )
{
m_size =
 
new int(*shoe.m_size);
m_brand =
 
new string(*shoe.m_brand);
}
// In main()
Shoe a(7, "abc");
Shoe b(4, "edf");
b = a;
Shoe a
-------------
int *m_size
string *m_brand
7
abc
Shoe b
-------------
int *m_size
string *m_brand
4
edf
What happened to the
memory b was pointing
to first???
What’s wrong with this?
void  Shoe::operator=( const Shoe& shoe )
{
 
*m_size = *shoe.m_size;
 
*m_brand = *shoe.m_brand;
}
Shoe a(7, "abc");
Shoe b(4, "edf");
Shoe c(9, "ghi");
c = b = a;
How does the c = b
work, when b = a
returns nothing??
Fixed
Shoe& Shoe::operator=( const Shoe& shoe )
{
 
*m_size = *shoe.m_size;
 
*m_brand = *shoe.m_brand;
 
return *this;
}
Shoe a(7, "abc");
Shoe b(4, "edf");
Shoe c(9, "ghi");
c = b = a;
What’s this?
this
 – a pointer to
the current object
 
Self-Assignment
 
class RentalSystem {
 
public:
  
// Assume constructor, other methods…
  
RentalSystem& operator=(
   
const RentalSystem & rs )
 
private:
  
Customer *m_customers;
  
int m_nbrOfCustomers;
};
 
RentalSystem& RentalSystem::operator=(
   
const RentalSystem & rs )
{
 
delete [] m_customers;
 
 
m_customers = new Customer[rs.m_nbrOfCustomers];
 
for (int i = 0; i < rs.m_nbrOfCustomers; ++i)
  
m_customers[i] = rs.m_customers[i];
 
 
return *this;
}
What happens when you do
the following?
 
RentalSystem r;
// Add customers…
r = r;
Protect from Self-Assignment
 
RentalSystem& RentalSystem::operator=(
   
const RentalSystem & rs )
{
 
// If this is NOT the same object as rs
 
if ( this != &rs )
 
{
  
delete [] m_customers;
 
  
m_customers = new Customer[rs.m_nbrOfCustomers];
  
for (int i = 0; i < rs.m_nbrOfCustomers; ++i)
   
m_customers[i] = rs.m_customers[i];
 
}
 
 
return *this;
}
 
Announcements
 
Project 3 is out – get started now!
Due Thursday, March 31st
 
Exam 2 is in 2 weeks
Will focus heavily on:
Classes
Inheritance
Linked Lists
Dynamic Memory
 
 
35
Slide Note
Embed
Share

Explore the concept of friend functions and classes in C++, allowing direct access to private variables outside a class. Learn how to utilize these features for accessing private members, testing functionality, improving speed, and overloading operators effectively. Discover the benefits and applications of using friend functions and classes in your C++ programs.

  • C++
  • Friend Functions
  • Friend Classes
  • Access Control
  • Operator Overloading

Uploaded on Aug 06, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. CMSC202 Computer Science II for Majors Lecture 13 Friends and More Dr. Katherine Gibson www.umbc.edu

  2. Last Class We Covered Linked Lists Traversal Creation Insertion Deletion 2 www.umbc.edu

  3. Any Questions from Last Time? www.umbc.edu

  4. Todays Objectives To cover some miscellaneous topics: Friends Destructors Freeing memory in a structure Copy Constructors Assignment Operators 4 www.umbc.edu

  5. Friend Functions and Classes www.umbc.edu

  6. Why Have Friends? Giving direct access to private variables is not possible if the function is not a class method But using accessors can be cumbersome, especially for something like an overloaded insertion operator (<<) Use a friend function to give direct access, even though the function is not called on an object of that class 6 www.umbc.edu

  7. Friend Functions Non-member functions that have member-style access Function is declared inside the class Will be public regardless of specifier Designate using the friend keyword friend void aFriendFunction(); 7 www.umbc.edu

  8. Friend Classes Classes can also be declared to be friends of another class class Milo { public: friend class Otis; }; the Otis class now has access to all of the private members of the Milo class class Otis { ... }; 8 www.umbc.edu

  9. Forward Declarations When one class references another in its definition, we need a forward declaration Tell the compiler it exists, without defining it In order to reference the Otis class before it s defined, we need something similar: class Otis; before the Milo class declaration 9 www.umbc.edu

  10. Using Friends Why give access to private member variables? Useful for testing functionality Increased speed Operator overloading Enhances encapsulation A function being a friend is specified in the class 10 www.umbc.edu

  11. Destructors www.umbc.edu

  12. Destructors Destructors are the opposite of constructors Used when delete() is called on an instance of a user-created class Compiler automatically provides one for you Does not take into account dynamic memory If your class uses dynamic memory, you must write a better destructor to prevent memory leaks! 12 www.umbc.edu

  13. Destructor Example: Date Let s say we have a new member variable of our Dateclass called m_next_holiday Pointer to a string with name of the next holiday class Date { private: int m_month; int m_day; int m_year; string *m_next_holiday ; }; 13 www.umbc.edu

  14. Destructor Example: Date We will need to update the constructor Date::Date (int m, int d, int y, string next_holiday) { SetMonth(m); SetDay(d); SetYear(y); m_next_holiday = new string; *m_next_holiday = next_holiday; } What other changes do we need to make to a class when adding a new member variable? 14 www.umbc.edu

  15. Creating a Destructor We also now need to create a destructor of our own: ~Date(); // our destructor Destructors must have a tilde at the front Similar to a constructor: Destructor has no return type Same name as the class 15 www.umbc.edu

  16. Basic Destructor Definition The destructor needs to free all of the dynamically allocated memory Otherwise we will have memory leaks Most basic version of a destructor Date::~Date() { delete m_next_holiday; } 16 www.umbc.edu

  17. Security and Carefulness Date::~Date() { delete m_next_holiday; } This works, but it isn t very secure for the data, and it isn t very careful with our pointers What if someone gets access to this memory later? What if my code tries to access m_next_holiday after it s been deleted? 17 www.umbc.edu

  18. Ideal Destructor Definition Clears all information and sets pointers to NULL Date::~Date() { // clear member variable info m_day = m_month = m_year = 0; *m_next_holiday = ""; // free and set pointers to NULL delete m_next_holiday; m_next_holiday = NULL; } Why aren t we using the mutator functions here? 18 www.umbc.edu

  19. Freeing Memory Done using the delete() function Takes a pointer as an argument: delete(grades); delete(letters); delete() does not work recursively For each individual allocation, there must be an individual call to free that allocated memory Called in a sensible order 19 www.umbc.edu

  20. Freeing in Order In what order would you free the nodes of this linked list? A B C D E 20 www.umbc.edu

  21. Freeing in Order In what order would you free the nodes of this binary tree? A B C D E F G H 21 www.umbc.edu

  22. Copy Constructors and Assignment Operators www.umbc.edu

  23. Copying Objects When does C++ make copies of objects? Pass by value Return by value Assignment and New object initialized from existing object www.umbc.edu

  24. Copy Constructor Initialize an object based on an existing object Examples: int a = 7; int b(a); // Copy constructor Shoe shoeOfMJ( Nike , 16 ); Shoe myShoe( shoeOfMJ ); // Copy www.umbc.edu

  25. Copy Constructor Use when dynamic memory is allocated Syntax: Prototype: ClassName( const ClassName& obj ); Implementation: ClassName::ClassName( const ClassName& obj ) { // code to dynamically allocate data } www.umbc.edu

  26. Why do we care? Remember Assignment (by default) makes a direct copy of data members With dynamic memory this would be copying pointers 7 Class ------------- int *data1 string *data2 Object *data3 Class ------------- int *data1 string *data2 Object *data3 abc Foo bar www.umbc.edu

  27. What do we want? Each object should have own memory allocated to members 7 Class ------------- int *data1 string *data2 Object *data3 7 Class ------------- int *data1 string *data2 Object *data3 abc abc Foo bar Foo bar www.umbc.edu

  28. Example class Shoe { public: Shoe( const Shoe& shoe ); private: int *m_size; string *m_brand; What s going on here? }; Shoe::Shoe( const Shoe& shoe ) { m_size = new int( *shoe.m_size ); m_brand = new string( *shoe.m_brand ); } www.umbc.edu

  29. What else? Assignment Operator Define if using dynamic memory Syntax: Prototype: ClassName& operator=( const ClassName& obj ); Definition: ClassName& ClassName::operator=( const ClassName& obj ) { // Deallocate existing memory, if necessary // Allocate new memory } www.umbc.edu

  30. Whats Wrong With This? Shoe a ------------- int *m_size string *m_brand Shoe& Shoe::operator=( const Shoe& shoe ) { m_size = new int(*shoe.m_size); m_brand = new string(*shoe.m_brand); } 7 abc Shoe b ------------- int *m_size string *m_brand 4 edf // In main() Shoe a(7, "abc"); Shoe b(4, "edf"); What happened to the memory b was pointing to first??? b = a; www.umbc.edu

  31. Whats wrong with this? void Shoe::operator=( const Shoe& shoe ) { *m_size = *shoe.m_size; *m_brand = *shoe.m_brand; } Shoe a(7, "abc"); Shoe b(4, "edf"); Shoe c(9, "ghi"); How does the c = b work, when b = a returns nothing?? c = b = a; www.umbc.edu

  32. Fixed Shoe& Shoe::operator=( const Shoe& shoe ) { *m_size = *shoe.m_size; *m_brand = *shoe.m_brand; return *this; } What s this? this a pointer to the current object Shoe a(7, "abc"); Shoe b(4, "edf"); Shoe c(9, "ghi"); c = b = a; www.umbc.edu

  33. Self-Assignment class RentalSystem { public: // Assume constructor, other methods RentalSystem& operator=( const RentalSystem & rs ) private: Customer *m_customers; int m_nbrOfCustomers; }; What happens when you do the following? RentalSystem r; // Add customers r = r; RentalSystem& RentalSystem::operator=( const RentalSystem & rs ) { delete [] m_customers; m_customers = new Customer[rs.m_nbrOfCustomers]; for (int i = 0; i < rs.m_nbrOfCustomers; ++i) m_customers[i] = rs.m_customers[i]; } return *this; www.umbc.edu

  34. Protect from Self-Assignment RentalSystem& RentalSystem::operator=( const RentalSystem & rs ) { // If this is NOT the same object as rs if ( this != &rs ) { delete [] m_customers; m_customers = new Customer[rs.m_nbrOfCustomers]; for (int i = 0; i < rs.m_nbrOfCustomers; ++i) m_customers[i] = rs.m_customers[i]; } return *this; } www.umbc.edu

  35. Announcements Project 3 is out get started now! Due Thursday, March 31st Exam 2 is in 2 weeks Will focus heavily on: Classes Inheritance Linked Lists Dynamic Memory 35 www.umbc.edu

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#