C++ Classes – Constructor(s) (Pt.2)
C. Papachristos
Robotic Workers Lab
University of Nevada, Reno
CS-202
Course , Projects , Labs:
Your 3rd Project Deadline is this Wednesday 2/12.
Course Week
CS-202 C. Papachristos
Monday | Tuesday | Wednesday | Thursday | Friday | | Sunday |
|
|
| Lab (8 Sections) |
| | |
| CLASS | PASS Session | CLASS |
| | |
PASS Session | | Project DEADLINE | NEW Project | PASS Session | | PASS Session |
Today’s Topics
CS-202 C. Papachristos
C++ Classes Cheatsheet
Initializer List(s)
static Members – Variables / Functions
Class Cheatsheet
Constructor(s):
Special Function:
“Constructors have no names and cannot be called directly.”
“They are invoked when instatintation takes place.”
“They are selected according to the rules of initialization.”
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Classes
CS-202 C. Papachristos
Class Cheatsheet
Default (empty) ctor:
Car();
Car::Car(){
strcpy(m_licensePlates, DFT_PLTS);
m_gallons = DFT_GLNS;
m_mileage = 0;
m_engineTiming = _def_DFT_TIM;
}
Note:
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Overloaded (parametrized) ctor:
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car::Car(char licPlts[PLT], float glns,
float mileage, const double engTim[VLV]){
strcpy(m_licensePlates, licPlts);
m_gallons = glns;
m_mileage = mileage;
for (int i=0; i<VLV; ++i)
m_engineTiming[i] = engTim[i];
}
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Overloaded (parametrized) ctor:
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car::Car(char licPlts[PLT], float glns,
float mileage, const double engTim[VLV]){
/* num of args resolves implementation */
}
Note:
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Overloaded (parametrized) ctor:
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car car("Gandalf", 5. ,0. , new double[VLV]
{0.,1.,2.,3.,…,3.,0.,1.,2.});
Car car("Gandalf", 5. ,0.);
Car car("Gandalf", 5.);
Car car("Gandalf");
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
or
or
or
No Parameter skipping !
Classes
CS-202 C. Papachristos
Class Cheatsheet
Overloaded (parametrized) ctor:
Caveat:
Car(char licPlts[PLT], float glns);
Car(char[PLT], float);
Car(char licPlts[PLT], float mlg);
Car(char[PLT], float);
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Car(const Car &car);
Car::Car(const Car & car){
strcpy(m_licensePlates,car.m_licensePlates);
m_gallons = car.m_gallons;
m_mileage = car.m_mileage;
for (int i=0; i<VLV; ++i)
m_engineTiming[i] = car.m_engineTiming[i];
}
Same Class:
class Car {
public:
Car();
Car(char licPlts[PLT],
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char m_licensePlates[PLT];
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Class now contains raw Pointer Member (char*):
Car::Car(){
m_licensePlates = (char*)malloc(PLT);
/* rest of Default ctor statements */
}
Car::Car(const char* licPlts, float glns,
float mileage, const double engTim[VLV]){
m_licensePlates = (char*)malloc(PLT);
/* rest of Overloaded ctor statements */
}
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Shallow-Copy ctor copies raw Pointer, not Data!
Car myCar("Gandalf");
Car myCarCpy(myCar);
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
myCar |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Values
myCarCpy |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Shallow-Copy ctor copies raw Pointer, not Data!
Car myCar("Gandalf");
Car myCarCpy(myCar);
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
myCar |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Values
0.
1.
2.
…
0.
1.
2.
0.
1.
2.
…
0.
1.
2.
Array
(non-Raw)
myCarCpy |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Shallow-Copy ctor copies raw Pointer, not Data!
Car myCar("Gandalf");
Car myCarCpy(myCar);
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
myCar |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
G
a
n
d
a
l
f
0
Values
0.
1.
2.
…
0.
1.
2.
0.
1.
2.
…
0.
1.
2.
myCarCpy |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Array
(non-Raw)
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Shallow-Copy ctor copies raw Pointer, not Data!
Car myCar("Gandalf");
Car myCarCpy(myCar);
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
myCar |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
G
a
n
d
a
l
f
0
Values
0.
1.
2.
…
0.
1.
2.
0.
1.
2.
…
0.
1.
2.
myCarCpy |
m_licensePlates(*) |
m_gallons, m_mileage |
m_engineTiming[VLV] |
Pointing-to
Array
(non-Raw)
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Deep-Copy ctor will allocate-&-copy Data!
Function Definition:
Car::Car(const Car &car){
m_licensePlates = (char*)malloc(PLT);
strcpy(m_licensePlates,car.m_licensePlates);
m_gallons = car.m_gallons;
m_mileage = car.m_mileage;
for (int i=0; i<VLV; ++i)
m_engineTiming[i] = car.m_engineTiming[i];
}
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Car myCar("Gandalf");
Car myCarCpy(myCar);
myCar.m_licensePlates[4] = 0;
cout << myCar.m_licensePlates << ","
<< myCarCpy.m_licensePlates << endl;
Shallow-Copy ctor will only copy raw Pointer:
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Classes
CS-202 C. Papachristos
Class Cheatsheet
Copy (class-object) ctor:
Car myCar("Gandalf");
Car myCarCpy(myCar);
myCar.m_licensePlates[4] = 0;
cout << myCar.m_licensePlates << ","
<< myCarCpy.m_licensePlates << endl;
Explicit Deep-Copy ctor will allocate-copy Data:
Note:
class Car {
public:
Car();
Car(const char * licPlts,
float glns=DFT_GLNS, float mlg=0,
const double engTim[VLV]=DFT_TIM);
Car(const Car & car);
float addGas(float gallons);
float getGallons() const ;
float getMileage() const ;
char * m_licensePlates;
protected:
float m_gallons;
float m_mileage;
private:
bool setEngineTiming(double[VLV]);
double m_engineTiming[VLV];
};
Constructor(s)
CS-202 C. Papachristos
Implementations
Member Initializer List(s)
Syntax (in Function Implementation only):
Date::Date(int month, int day, int year) :
m_month(month) ,
m_day(day) ,
m_year(year)
{
/* Overloaded constructor statements */
}
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y);
Date(const Date & date);
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
};
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y);
Date(const Date & date);
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
};
Constructor(s)
CS-202 C. Papachristos
Implementations
Member Initializer List(s)
Syntax (in Function Implementation only):
Date::Date(int month, int day, int year) :
m_month(month) , m_day(day) , m_year(year) {
/* no more statements necessary for init */
}
An alternative Implementation to assignment statements:
Date::Date(int month, int day, int year){
m_month = month;
m_day = day;
m_year = year;
}
Constructor(s)
CS-202 C. Papachristos
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y,
bool gregorian=true);
Date(const Date & date);
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
const bool m_gregorian;
};
Implementations
Member Initializer List(s)
Syntax (in Function Implementation only):
Date::Date(int m, int d, int y, bool gregorian) :
m_month(m), m_day(d), m_year(y),
m_gregorian(gregorian) {
}
Assignment statements not performed at Instantiation-time:
Date::Date(int m, int d, int y, bool gregorian){
m_month = m; m_day = d; m_year = y;
m_gregorian = gregorian;
}
const Variable:
Not allowed !
Constructor(s)
CS-202 C. Papachristos
class Date{
public:
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month = DFT_M;
int m_day = DFT_D;
int m_year = DFT_Y;
const bool m_gregorian
= true;
};
Implementations
Default Member Initialization (since C++11):
Syntax (in Class Declaration only)
class <class_name> { …
<type_id> m_var1 = const_literal_val;
}
Example (no Constructors defined for Date):
Date myDate;
cout<<myDate.getM()<<myDate.getD()<<myDate.getY();
DFT_M DFT_D DFT_Y
Warning:
Ignored if it also appears in a Member Initializer List !
Date():m_year(2457797),m_gregorian(false){}
Constructor(s)
CS-202 C. Papachristos
Implementations
Delegating Constructor (since C++11):
Date(bool gregorian) :
Date(DFT_M, DFT_D, DFT_Y, gregorian)
{ /* rest of delegating ctor body … */ }
Delegates the Parametrized one as its Target ctor:
Date dateDftCtor;
Normal Parametrized ctor calls:
Date dateParam(DFT_M, DFT_D, DFT_Y, true);
Date dateDftParam(DFT_M);
Delegating ctor call:
Date dateDeleg(true);
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y,
bool gregorian=true);
Date(bool gregorian):
Date(DFT_M,DFT_D,DFT_Y,
gregorian) { … }
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
const bool m_gregorian;
};
Constructor(s)
CS-202 C. Papachristos
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y,
bool gregorian=true);
Date(const Date & date);
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
const bool m_gregorian;
};
Aggregate Class Constructor(s)
Composition:
Example:
class Vacation {
…
private:
Date m_startDay;
};
line
point
x
y
point
x
y
Remember structs:
Constructor(s)
CS-202 C. Papachristos
class Date{
public:
Date();
Date(int month,
int day=DFT_D,
int year=DFT_Y,
bool gregorian=true);
Date(const Date & date);
void setM/D/Y(int mdy);
int getM/D/Y() const;
void shiftNextDay();
private:
int m_month, m_day,
m_year;
const bool m_gregorian;
};
Aggregate Class Constructor(s)
Member Initializer List(s)
Class-with-Composition Initialization:
class Vacation{
public:
Vacation(int month, int day, int numDays);
private:
Date m_startDay;
int m_tripLength;
};
Vacation::Vacation(int m, int d, int numDays) :
m_startDay(m, d) , m_tripLength(numDays) {
/* constructor code, m_startDay initialized !*/
}
Calls Date ctor at Vacation Instantiation-time !
Static Variables
static local variables – in general:
int nonStaticLocal(){
int a = 0;
++a;
return a;
}
int b = nonStaticLocal(); 1
int c = nonStaticLocal(); 1
int d = nonStaticLocal(); 1
Static Member(s)
CS-202 C. Papachristos
int staticLocal(){
static int a = 0;
++a;
return a;
}
int b = staticLocal(); 1
int c = staticLocal(); 2
int d = staticLocal(); 3
Destroyed when function returns.
Persists across function calls.
Static Member(s)
CS-202 C. Papachristos
Static and Classes
static Class Member Variables:
If one Object modifies it, all Objects will see the change.
Not “bound” to a specific Object, but mark a state of the Class itself.
Syntax:
class <class_name> { …
static <type_id> static_classVarName;
}
Usual utility is for “tracking”, i.e. :
Static Member(s)
CS-202 C. Papachristos
Static and Classes
static Member Functions:
Bound to Class itself, can only use static Member Data, static Member Functions.
Syntax:
class <class_name> { …
static <ret_type_id> static_classFunctionName( <params_list> );
}
Can be called outside of Class.
Example: Server::getTurn();
Example: myServer.getTurn();
Static Member(s)
CS-202 C. Papachristos
Static and Classes - Example
Declaration of static Data Members
Definition of static Data Members
Note:
It is necessary to provide a static Data Member’s Definition separately.
Side-Note:
C++17 introduces inline (special keyword use) declaration of static data members in class declarations.
#ifndef SERVER_INTERFACE_H_
#define SERVER_INTERFACE_H_
class ServerInterface {
public:
ServerInterface();
~ServerInterface();
bool doWork(int * data, size_t dataSize);
static bool resourceAvailable();
private:
void sendToSharedResource(bool & done);
void sharedResourceReleased();
bool m_server_busy;
bool m_done;
static size_t active_servers;
static size_t free_servers;
};
#endif
Static Member(s)
CS-202 C. Papachristos
Static and Classes - Example
#include <iostream>
#include "ServerInterface.h"
size_t ServerInterface::active_servers = 0;
size_t ServerInterface::free_servers = 0;
ServerInterface::ServerInterface() : m_server_busy(false) {
++active_servers; ++free_servers;
}
ServerInterface::~ServerInterface() {
active_servers > 0 ? --active_servers,--free_servers : 0;
}
bool ServerInterface::doWork(int * data, size_t dataSize) {
if (!m_server_busy) {
m_server_busy = true; m_done = false;
sendToSharedResource(m_done);
return true;
}
else if (m_done) {
sharedResourceReleased();
m_server_busy = false;
}
return false;
}
bool ServerInterface::resourceAvailable()
{ return active_servers>0 && free_servers>0; }
void ServerInterface::sendToSharedResource(bool & done)
{ --free_servers; //done will at some point be set to true }
void ServerInterface::sharedResourceReleased()
{ ++free_servers; }
#ifndef SERVER_INTERFACE_H_
#define SERVER_INTERFACE_H_
class ServerInterface {
public:
ServerInterface();
~ServerInterface();
bool doWork(int * data, size_t dataSize);
static bool resourceAvailable();
private:
void sendToSharedResource(bool & done);
void sharedResourceReleased();
bool m_server_busy;
bool m_done;
static size_t active_servers;
static size_t free_servers;
};
#endif
Static Member(s)
CS-202 C. Papachristos
Static and Classes - Example
Separate Objects, but their behavior interfaces, due to the unique status of entire Class.
#include "DataProvider.h" // has a function: int * pull_data();
#include "ServerInterface.h"
bool assignWorker(ServerInterface * workers, int workers_size,
int * data, int data_size) {
for (size_t i=0; i<workers_size; ++i) {
if (workers[i].doWork(data, data_size))
return true;
}
return false;
}
int main() {
ServerInterface si_workers[3];
int * data_to_process = NULL;
do {
if (ServerInterface::resourceAvailable()) {
data_to_process = pull_data();
if (data_to_process != NULL) {
assignWorker(si_workers, 3, data_to_process, 1000);
}
}
} while (data_to_process != NULL);
return 0;
}
Time for Questions !
CS-202
CS-202 C. Papachristos