COMP345:
Advanced Program Design with C++
Lecture 4
Aggregate data types (part b)
Department of Computer Science and Software Engineering Concordia University
Contents
struct
class
inline functions and methods const specifier
static specifier
friend
Constructors and destructors
Static members
A member of a class can be declared as static, which means that this member is a class member, i.e. it belongs to the class as a whole an can be called on the class rather than on the objects.
If it is a data member, its value is unique across all objects of the class, i.e. it is a class global variable.
If a member function is declared as static, it can only use other members that are also declared as static.
Used to define state and behavior that is independent of any particular objects state instantiated from this class.
Static member variables are generally initialized outside of the class declaration. Only constant static integral members can be initialized inside of the class declaration. The initialized value must be a constant expression.
Other languages allow static classes (e.g. C#), which C++ does not have. Joey Paquet, 2007-2020
3
Static members: use and initialization
4
Pitfall: There are variations of these restrictions depending on the specific version/standard of C++
you use.
Joey Paquet, 2007-2020
Static variables
Non-member variables can also be declared as static, which has a slightly different meaning:
When you declare a variable or function at file scope
the static keyword specifies that the variable or function has internal linkage, i.e. it cannot be referred to outside of the compilation unit in which it is declared.
When you declare a local variable to a function as static, the variable has static duration, i.e. its value is kept even when the execution goes out of the scope of this function. In other words, it is a global variable that has local scope to this function.
5
Joey Paquet, 2007-2020
Static variables
All static variables persist from the start of the execution of the program until the program terminates.
Depending on where it is used, the static keyword has different meaning for non- member variables:
Variable d has local scope and no external linkage.
So does variable c, plus, it retains its value even when the f() function is not being
executed, and is initialized only once.
Both a and b can be accessed from the point of declaration by all the code to the end of
the file. But a can be used in other files because it has external linkage.
6
Joey Paquet, 2007-2020
Static: sum-up
To sum-up:
A variable declared static within the body of a function maintains its value
between invocations of the function.
A variable declared static within a file scope is accessible by all functions within that compilation unit. However, it is not accessible by functions from other compilation units.
Free functions declared static within a compilation unit may only be called by other functions within that compilation unit.
static class members exist as members of the class rather than as an instance in each object of the class. There is only a single instance of each static data member for the entire class.
Non-static member functions can access all data members of the class: static and non-static.
static member functions can only operate on the static data members, or call other static member functions.
Joey Paquet, 2007-2020
7
Contents
struct
class
inline functions and methods const specifier
static specifier
friend
Constructors and destructors
Friends
In principle, private and protected members of a class cannot be accessed from outside the class in which they are declared.
A friend (function or class) of a class may access the members designated as private or protected.
Friends are functions/methods or classes declared as such within a class.
Friends are not members, so they are not inherited from a superclass.
Widely criticized for being a rogue feature:
Makes the language more complex to implement. Breach of the information hiding principle.
If overused, creates a proliferation of exceptions to information hiding, and thus confusion in the design.
Joey Paquet, 2007-2020
9
Friends (free function friend)
10
Joey Paquet, 2007-2020
COMP 345 Advanced Program Design with C++ 11
Friends (free function friend)
Concordia University Department of Computer Science and Software Engineering
Joey Paquet, 2007-2020
COMP 345 Advanced Program Design with C++ 12
Friends (friend class)
Concordia University Department of Computer Science and Software Engineering
Joey Paquet, 2007-2020
COMP
13
Friends (friend class)
Concordia University Department of Computer Science and Software Engineering
Joey Paquet, 2007-2020
COMP 345 14
Friends (member function friend)
Concordia University Department of Computer Science and Software Engineering
Joey Paquet, 2007-2020
COMP 345 C++ 15
Friends (member function friend)
Concordia University Department of Computer Science and Software Engineering
Joey Paquet, 2007-2020
Contents
struct
class
inline functions and methods const specifier
static specifier
friend
Constructors and destructors
COMP 345 Advanced Program Design with C++ 17
Constructors and destructors
C++ relies on constructors and destructors for the creation and destruction of objects. A constructor is called any time an object is instantiated:
Using a variable declaration (allocated on the stack): DayOfYear birthday;
Using a pointer variable and calling the new operator (allocated on the heap): DayOfYear *today = new DayOfYear();
During an explicit call to a constructor: birthday = DayOfYear();
The destructor is called any time an object is to be destroyed:
When going out of a function scope, all variables declared in that function scope are destroyed by automatically calling their destructor before the stack frame is popped from the function call stack.
When the delete operator is explicitly called on a pointer variable. Joey Paquet, 2007-2020
COMP 345 Advanced Program Design with C++ 18
Constructors and destructors
To sum-up, variables allocated on the stack are destroyed as we get out of the block`s scope, but objects allocated on the heap using new need to be manually destroyed using delete.
Rule of thumb: for every new, there should be a corresponding delete somewhere.
Joey Paquet, 2007-2020
19
Constructor declaration and implementation
A constructor is a member function that has the same name as its class.
Can have as many constructors as needed.
The default constructor is the constructor that does not take any parameter. It is the one called when no specific constructor is mentioned during instantiation.
If you include no constructors in your class, the compiler will provide an automatically generated default constructor for basic memory allocation of data members, but not to the objects they are pointing to, if they are pointers.
If you include at least one constructor, it will not be generated, thus you may end up having no default constructor defined.
Rule of thumb: if you define your own constructor(s), make sure that you provide a default constructor, as the default constructor is likely to be called implicitly by the runtime system.
Joey Paquet, 2007-2020
20
Constructor declaration and implementation
Constructors are differentiated by their parameter lists.
Parameters are generally used to pass values for data members initialization.
The call to the default constructor should not use parentheses, as it would make it syntactically equivalent to a function header declaration:
DayOfYear date3(); // function header declaration
Joey Paquet, 2007-2020
21
Constructor declaration and implementation
For the implementation, constructors are easily recognizable by being referred to as className::className :
C++ also provides a constructor initialization list feature that allows one to declare how are the initialization mappings done between the parameters of the constructor and the data members of the class:
The preceding two examples are implementing two constructors whose effect is the same.
Joey Paquet, 2007-2020
22
Constructor declaration and implementation
Constructorscanalsoactas guards.
A guard verifies that certain preconditions are met before proceeding and may reject the operation if preconditions are not met.
The constructor may verify that the values passed as parameters to the constructors are valid according to the specifications of the variable they are to initialize.
Ifvalidpreconditionsarenotmet, then the constructor may report an error or throw an exception.
Includingguardingconditionsin your constructors leads to more robust implementation.
Joey Paquet, 2007-2020
23
Constructor declaration and implementation
Constructors can also be explicitly called in the initialization list of the constructors of a class that contains a data member which is an object of another class.
The initialization list is the only place where a base class constructor can be called.
Joey Paquet, 2007-2020
Constructors: call chain
24
struct A {
// A::A() is implicitly-defined
};
struct B : A {
// B::B() is implicitly-defined, calls A::A()
};
struct C {
A class Name;
// C::C() is implicitly-defined, calls A::A()
};
struct G : B, C {
A class Name;
// G::G() is implicitly-defined
// calls B::B(), C::C(), then A::A()
// complete chain: A::A(), B::B(), A::A(), C::C(), A::A(), G::G()
};
A
B
C
A
G
A
If a constructor does not explicitly call the base class constructors in its initialization list, the base class default constructors are called, in the order in which the base classes are declared.
This creates a chain of base constructors calls up in the inheritance hierarchy.
After all base class constructors have been called, if a constructor does not explicitly initialize some of its data members in the initialization list, the members default constructors are called in the order in which the members are declared.
Joey Paquet, 2007-2020
Constructors: subtelties
25
struct F {
int& ref; // reference member: must be initialized
const int c; // const member: must be initialized
// F::F() is implicitly defined as deleted because:
// c and ref cannot be assigned a value using the automatically generated // default constructor.
// if we explicitly declare a default constructor that does nothing, // the compiler complains that ref and c are not initialized.
// F() {};
// The only way to properly create an object of that kind // is to have a constructor such as:
// F(int newref, int newc) : ref(newref), c(newc) {
// }
};
If a struct/class contains constant/reference data members, they must be initialized in an explicitly defined default constructor.
If not, the default constructor is defined as deleted (i.e. does not exist). There are many other such subtelties. Beware!
Joey Paquet, 2007-2020
Destructors: call chain
#include
A() { cout << “A::A()” << endl; }~A() { cout << “A::~A()” << endl; } };creating an A: A::A() creating a B: A::A()B::B() creating a C: A::A() C::C() creating a G: A::A() B::B() A::A() C::C() A::A() G::G() deleting all: G::~G() A::~A() C::~C() A::~A() B::~B() A::~A() C::~C() A::~A() B::~B() A::~A() A::~A()26 Astruct B : A { B() { cout ~B() {cout};struct C {A end;C() { cout~C() {cout<< <<<< <<“B::B()” << endl; } “B::~B()” << endl; }”C::C()” << endl; } “C::~C()” << endl; }”G::G()” << endl; } “G::~G()” << endl; }BC AG A };struct G : B, C {A end;G() { cout <<~G() {cout <<};int main() {cout << “creating an A: ” << endl; A end; cout << “creating a B: ” << endl; B end; cout << “creating a C: ” << endl; C end; cout << “creating a G: ” << endl; G end; cout << “deleting all: ” << endl;} Destructors are called in the exact reverse order as the constructors. Joey Paquet, 2007-2020End part b
Reviews
There are no reviews yet.