This post is also available in: en, en and en
Creating Robust Classes¶
In chapter three we coded a simple class in C++ using the syntax that we had introduced in that chapter. Of course, it was not possible (or even diserable) to discuss all possible 'syntax avenues' because doing so would be confusing. In this chapter we wish to create more robust and efficient classes and we realise this goal by using some of the syntax that C++ offers. In particular, we address a number of issues that have to do with data and object security, such as:
Issue 1: Ensuring that objects and their data are created in a safe way.
Issue 2: Accesing and using objects in a safe way; avoiding side-effects.
Issue 3: Working with object references rather than copies of objects.
Issue 4: Optimization: static objects and static member data.
This is quite a lot of territory to cover and the results in this chapter will be used again and again throughout this book. Thus, this chapter is a vital link to future chapters.
The most important topics are:
- Passing parameters to functions by value or by reference.
- Function overloading: ability to define several functions having the same name.
- More on constructors.
- Not all functions need be member functions: non-member functions.
- The
const
keyword and its consequences for C++ applications.
After having understood these topics and having implemented them in simple classes the reader will have reached a level of expertise approaching yellow belt. We discuss these topics not only because they are supported in C++ but because they help us become good C++ developers. They also promote the reliability and efficiency of our code.
Call by reference and call by value¶
In C++ one can create functions taking zero or more arguments in their parameter list. To this end, we need discuss in what forms these arguments are created and used in a function. We take a simple example to motivate what we mean. Let us consider a function that calculates the larger of two numbers:
double Max(double x, double y)
{
if (x > y)
return x;
return y;
}
This is a very simple function of course and in this case we say that the inputs parameters x
and y
are used in a call-by-value manner; this means that copies of these variables are made on the stack when the function is called:
#include <iostream>
{
double d1 = 1.0;
double d2 = -34536.00;
// Copies of d1 and d2 offered to the function Max()
double result = Max(d1, d2);
std::cout << "Maxvalue is " << result << std::endl;
}
In this case we work with copies of d1
and d2
in the body of Max()
and not d1
and d2
themselves. This process is taken care of automatically and you do not have to worry about this as programmer.
The call-by-value technique is also applicable, not only to built-in-types as we have just seen but also to class instances (objects). This means that objects (even big
ones) will be copied if they are used in this call-by-value way. Let us take an example of a class having an embedded fixed-size array as member data:
class SampleClass
{
public: //
}
!cat Point.hpp
!cat Point.cpp
!cat TestPoint.cpp