0% found this document useful (0 votes)
109 views31 pages

CSCI 104 Classes: Mark Redekopp David Kempe Sandra Batista

Here are a few ways to initialize the members of the Student struct using a constructor initialization list: 1. Student(): name("Default"), id(0), scores(10) {} 2. Student(): name(), id(0), scores(10) {} 3. Student(): scores(10) {} 4. Student(): name("Default"), scores(10) {} The constructor initialization list allows you to initialize references, constants, and parent class members before the constructor body is executed. This avoids unnecessary constructor operations and ensures members are initialized as intended before use in the constructor body.

Uploaded by

Sumedha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
109 views31 pages

CSCI 104 Classes: Mark Redekopp David Kempe Sandra Batista

Here are a few ways to initialize the members of the Student struct using a constructor initialization list: 1. Student(): name("Default"), id(0), scores(10) {} 2. Student(): name(), id(0), scores(10) {} 3. Student(): scores(10) {} 4. Student(): name("Default"), scores(10) {} The constructor initialization list allows you to initialize references, constants, and parent class members before the constructor body is executed. This avoids unnecessary constructor operations and ensures members are initialized as intended before use in the constructor body.

Uploaded by

Sumedha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

1

CSCI 104
Classes
Mark Redekopp
David Kempe
Sandra Batista
2

OVERVIEW AND CONCEPTS


3

C Structs
• Needed a way to group values that are
related, but have different data types
• NOTE: struct has changed in C++! struct Person{
char name[20];
–C };
int age;

• Only data members int main()


{
• Some declaration nuances // Anyone can modify
– C++ // b/c members are public
Person p1;
• Like a class (data + member functions) p1.age = -34;
// probably not correct
• Default access is public return 0;
}
4

Classes & OO Ideas


• Classes are used as the primary way to organize code Protect yourself from users &
• Encapsulation protect your users from
– Place data and operations on data into one code unit themselves
– Keep state hidden/separate from other struct Machine{
programmers (or yourself) via private members Piece* pieces;
Engine* engine;
• Abstraction };
– Depend only on an interface! int main()
• Ex. a microwave…Do you know how it works? {
Machine m;
But can you use it?
– Hide implementation details to create low init_subsystemA(&m);
degree of coupling between different
change_subsystemB(&m);
components
• Unit of composition replace_subsystemC(&m);

– Create really large and powerful software systems from m.start();


tiny components // Seg. Fault!! Why?
}
• Define small pieces that can be used to compose larger pieces
– Delegation/separation of responsibility
• Polymorphism & Inheritance
– More on this later…
5

Coupling
• Coupling refers to how much components depend on each
other's implementation details (i.e. how much work it is to
remove one component and drop in a new implementation of
it)
– Placing a new battery in your car vs. a new engine
– Adding a USB device vs. a new video card to your laptop
• OO Design seeks to reduce coupling as much as possible by
– Creating well-defined interfaces to change (write) or access (read) the
state of an object
– Allow alternate implementations that may be more appropriate for
different cases
6

PARTS OF A CLASS
7

Parts of a C++ Class


• What are the main parts of a class IntLinkedList {
public:
class? IntLinkedList( );
IntLinkedList( int n ) ;
– Member variables ˜IntLinkedList( );
void prepend(int n);
• What data must be stored? void remove(int toRemove);
– Constructor(s) void printList();
void printReverse();
• How do you build an instance? private :
void printHelper(Item *p);
– Member functions Item ∗head;
• How does the user need to interact };
with the stored data?
– Destructor
• How do you clean up an after an
instance?
8

Notes About Classes


• Member data can be public or private (for now)
– Defaults is private (only class functions can access)
– Must explicitly declare something public
• Most common C++ operators will not work by default
(e.g. ==, +, <<, >>, etc.)
– You can't cout an object ( cout << myobject; won't work )
– The only one you get for free is '=' and even that may not work the
way you want (more on this soon)
• Classes may be used just like any other data type (e.g. int)
– Get pointers/references to them (Obj*, Obj&)
– Pass them to functions (by copy, reference or pointer)
– Dynamically allocate them (new Obj, new Obj[100])
– Return them from functions (Obj f1(int x);)
9

C++ Classes: Constructors


• Called when a class is instantiated
– C++ won't automatically initialize member variables class IntLinkedList {
public:
– No return value IntLinkedList( );
• Default Constructor IntLinkedList(int n);
˜IntLinkedList( );
– Can have one or none in a class ...
– Basic no-argument constructor };
– Has the name ClassName()
– If class has no constructors, C++ will make a default
• But it is just an empty constructor (e.g. Item::Item() { } )
• Overloaded Constructors
– Can have zero or more
– These constructors take in arguments
– Appropriate version is called based on how many and what type of
arguments are passed when a particular object is created
– If you define a constructor with arguments you should also define a default
constructor (otherwise no default constructor will be available)
10

Identify that Constructor


#include <string>
• Prototype what constructors #include <vector>
using namespace std;
are being called here int main()
{
string s1;
string s2("abc");

vector<int> dat(30);

return 0;
}
11

Identify that Constructor


#include <string>
• Prototype what constructors #include <vector>
using namespace std;
are being called here int main()

• s1
{
string s1;
string s2("abc");
– string::string()
// default constructor vector<int> dat(30);

• s2 return 0;
}
– string::string(const char* )

• dat
– vector<int>::vector<int>( int );
12

Initializing data members of a class

CONSTRUCTOR INITIALIZATION
LISTS
13

Consider this Struct/Class


• Examine this struct/class definition…
– How can I initialize the members?
#include <string>
#include <vector>
string name
struct Student
{ Student(); // constructor int id
std::string name; scores
int id;
std::vector<double> scores;
// say I want 10 test scores per student

};

int main()
{
Student s1;
}
14

Composite Objects
string name
#include <string> int id
#include <vector>
scores
• Fun Fact 1: Memory for an
struct Student
object comes alive before '{' {
std::string name;
of the constructor code int id;
• Fun Fact 2: Constructors std::vector<double> scores;
// say I want 10 test scores per student
for objects get called (and Student() /* mem allocated here */
can ONLY EVER get called) { // Can I call string & vector
// constructors to init. members?
at the time memory is name("Tommy Trojan");
id = 12313;
allocated scores(10);
}
};

int main()
{ Student s1;
//...
}
15

Initializing Members
• To recap: When an object is constructed the
individual members are constructed first
– Members constructors are called before object's
constructor

Class Obj
{ public: Type1 mem1 TypeA(){…}
Obj();
// public members
private: Type2 mem2 Members are
TypeB(){…}
Type1 mem1; constructed
Type2 mem2; first…
Type3 mem3 TypeC(){…}
Type3 mem3;
}; Obj …then Object
Obj(){…} constructor
called after
16

What NOT to do!


• So we CANNOT call constructors on data members INSIDE the
constructor)
– So what can we do??? Use initialization lists!
#include <string>
#include <vector> Stack Area of RAM

struct Student 0xbe4 scores


{ std::string name;
int id; 0xbe8 Tommy name
Student()
std::vector<double> scores; 0xbec 004000ca0
Return
link
// say I want 10 test scores per student
0xbf0
Student() /* mem allocated here */ name
main 0xbf4
{ // Can I do this to init. members? id s1
string name("Tommy"); // or 0xbf8 scores
// name("Tommy") 0xbfc Return
00400120
id = 12313; link

vector <double> scores(10); This would be


} "constructing"
}; name twice. It's
int main() too late to do it in
{ Student s1; the {…}
//...
}
17

Old Initialization Approach


Student::Student() Student::Student() :
{ name(), id(), scores()
name = "Tommy Trojan"; // calls to default constructors
id = 12313 {
scores.resize(10); name = "Tommy Trojan"; // now modify
} id = 12313
scores.resize(10);
}

If you write this…


The compiler will still generate this.

• Though you do not see it, realize that the default


constructors are implicitly called for each data
member before entering the {…}
• You can then assign values (left side code)
– But this is a 2-step process: default construct, then
replace with desired value
18

New Initialization Approach


Student::Student() : Student::Student() :
name(), id(), scores() /* compiler generated */ name("Tommy"), id(12313), scores(10)
{ {
name = "Tommy Trojan"; }
id = 12313
scores.resize(10);
}
Default constructors implicitly called and You would have to call the member
then values reassigned in constructor constructors in the initialization list context

• We can initialize with a 1-step process using a


C++ constructor initialization list
– Constructor(param_list) : member1(param/val), …, memberN(param/val)
{…}

• We are really calling the respective constructors


for each data member at the time memory is
allocated
19

Summary
Student::Student() Student::Student() :
{ name(), id(), scores()
name = "Tommy Trojan"; // calls to default constructors
id = 12313 {
scores.resize(10); name = "Tommy Trojan";
} id = 12313
scores.resize(10);
}
You can still assign data But any member not in the initialization list will
members in the {…} have its default constructor invoked before the
{…}

• You can still assign values in the constructor but realize that the
default constructors will have been called already
• So generally if you know what value you want to assign a data
member it's good practice to do it in the initialization list
Student::Student() :
name("Tommy"), id(12313), scores(10)
{ }

This would be the preferred approach especially for


any non-scalar members (i.e. an object)

Exercise: cpp/cs104/classes/constructor_init2
20

Calling Constructors
• You CANNOT use one constructor as a helper function to help
initialize members
– DON'T call one constructor from another constructor for your class
struct Student string name
{ std::string name;
int id
int id;
std::vector<double> scores; scores

Student()
{ name = "Tommy Trojan"; // default
id = -1; // default
scores(10); // default 10 assignments
}
Student(string n) Can we use Student() inside Student(string
{ Student(); name) to init the data members to defaults
name = n; and then just replace the name?
}
};
No!! Calling a constructor always allocates
another object. So rather than initializing the
int main()
members of s1, we have created some new,
{
anonymous Student object which will die at the
Student s1("Jane Doe");
end of the constructor
// more code...
}
21

Allocating and Deallocating Members


Type1 mem1 TypeA(){…}
• Members of an object

First
have their constructor Type2 mem2 TypeB(){…}
called automatically Type3 mem3 TypeC(){…}
before the Object's
ObjB
constructor executes ObjB(){…} Second

Construction
• When an object is Destructor is
~ObjB(){…} called first to
destructed the members ObjB cleanup whatever
members are
are destructed Type1 mem1 ~TypeA(){…} referencing…
automatically AFTER the …then the
object's destructor runs Type2 mem2 ~TypeB(){…}
destructor for
each data
Type3 mem3 ~TypeC(){…} member is called
automatically

Destruction
22

C++ Classes: Destructors


• Destructors are called when an object goes out of
scope or is freed from the heap (by “delete”) class Item
{ string s1;
• Destructors int* x; s1 "Hi"
– Can have one or none (if no destructor defined by the public:
x 0x148
programmer, compiler will generate an empty destructor) Item();
~Item();
– Have no return value
};
– Have the name ~ClassName() 0x148 7

– Data members of an object have their destructor's called Item::Item()


automatically upon completion of the destructor. { s1 = "Hi";
x = new int;
• Why use a destructor? *x = 7;
– Not necessary in simple cases }
– Clean up resources that won't go away automatically (e.g. Item::~Item()
when data members are pointing to dynamically {
allocated memory that should be deallocated when the delete x;
object goes out of scope) } // data members
// destructed here
– Destructors are only needed only if you need to do more
than that (i.e. if you need to release resources, close files,
deallocate what pointers are point to, etc.)
– The destructor need only clean up resources that are
referenced by data members.
23

OTHER IMPORTANT CLASS DETAILS


24

Member Functions
• Object member access uses
class Item
{ int val;
public:
dot (.) operator void foo();
void bar() const;

• Pointer-to-object member
};
void Item::foo()
{ val = 5; }
access uses arrow (->)
void Item::bar() const
operator { }

• Member functions have int main()


{
Item x;
access to all data members x.foo();
Item *y = &x;
of a class (*y).bar();
y->bar(); // equivalent
return 0;
• Use “const” keyword if it }

won't change member data


25

'const' Keyword
• const keyword can be used with
– Input arguments to ensure they aren't modified
– After a member function to ensure data members aren't modified by
the function
– Return values to ensure they aren't modified

string
string arg1 = "Hi" arg1
int& z =
objA.memFunc1(arg1);

int const &


ObjectA

int const & memFunc1(const string& s) const


{ return s == "Hi" ? mem1 : mem2; }
int string int
mem1 mem2 mem3 This Photo by Unknown Author
is licensed under CC BY-SA
26

Exercises
• cpp/cs104/classes/const_members
• cpp/cs104/classes/const_members2
• cpp/cs104/classes/const_return
27

C++ Classes: Other Notes


• Classes are generally split across two #ifndef STRING_H
#define STRING_H
files class string{
string();
– ClassName.h – Contains interface size_t length() const;
description /* ... */
};
– ClassName.cpp – Contains #endif
implementation details
• Make sure you remember to prevent string.h
multiple inclusion errors with your
header file by using #ifndef, #define, #include "string.h"
and #endif string::string()
#ifndef CLASSNAME_H { /* ... */ }

#define CLASSNAME_H size_t string::length() const


{ /* ... */ }
class ClassName { … };
string.cpp
#endif
28

Multiple Inclusion
class string{
• Often separate files may ... };

#include's of the same header string.h

file #include "string.h"


class Widget{
public:
• This may cause compiling string s;
};
errors when a duplicate
widget.h
declaration is encountered #include "string.h"
– See example #include "widget.h"
int main()
• Would like a way to include only { }

once and if another attempt to main.cpp


include is encountered, ignore it class string { // inc. from string.h
};
class string{ // inc. from widget.h
};
class Widget{
... }
int main()
{ }

main.cpp after preprocessing


29

Conditional Compiler Directives


#ifndef STRING_H
#define STRING_H
• Compiler directives start with class string{ ... };
#endif
'#'
– #define XXX string.h
• Sets a flag named XXX in the
#include "string.h"
compiler class Widget{
– #ifdef, #ifndef XXX … #endif public:
string s;
• Continue compiling code below };
until #endif, if XXX is (is not)
widget.h
defined
#include "string.h"
• Encapsulate header #include "string.h"

declarations inside a main.cpp

– #ifndef XX class string{ // inc. from string.h


#define XX };

… class Widget{ // inc. from widget.h

#endif ...
main.cpp after preprocessing
30

CONDITIONAL COMPILATION
31

Conditional Compilation
• Often used to compile int main()
additional DEBUG code {
int x, sum=0, data[10];
– Place code that is only needed for ...
debugging and that you would not want to for(int i=0; i < 10; i++){
execute in a release version sum += data[i];
#ifdef DEBUG
• Place code in a cout << "Current sum is ";
cout << sum << endl;
#ifdef NAME...#endif bracket #endif
}
• Compiler will only compile if a
cout << "Total sum is ";
#define NAME is found cout << sum << endl;

• Can specify #define in:


– source code stuff.cpp

– At compiler command line with $ g++ -o stuff –DDEBUG stuff.cpp


(-DNAME) flag
• g++ -o stuff –DDEGUG
stuff.cpp

You might also like