0% found this document useful (0 votes)
45 views

Programming in C and C++

This document provides an overview of key concepts in C++ including: - C++ supports fundamental data types from C as well as a new bool type - C++ allows user-defined types through classes which can contain data members and member functions - Namespaces allow related code to be grouped together to avoid naming collisions - Functions can be overloaded based on parameter types, and default arguments allow optional parameters - Constructors and destructors handle object initialization and cleanup and allow resources to be managed automatically

Uploaded by

John Pinchos
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)
45 views

Programming in C and C++

This document provides an overview of key concepts in C++ including: - C++ supports fundamental data types from C as well as a new bool type - C++ allows user-defined types through classes which can contain data members and member functions - Namespaces allow related code to be grouped together to avoid naming collisions - Functions can be overloaded based on parameter types, and default arguments allow optional parameters - Constructors and destructors handle object initialization and cleanup and allow resources to be managed automatically

Uploaded by

John Pinchos
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/ 21

Programming in C and C++

5. C++: Overloading, Namespaces, and Classes

Dr. Neel Krishnaswami


University of Cambridge
(based on notes from and with thanks to Anil Madhavapeddy, Alan Mycroft,
Alastair Beresford and Andrew Moore)

Michaelmas Term 2016-2017


C++
To quote Bjarne Stroustrup:

“C++ is a general-purpose programming language with a bias towards


systems programming that:
I is a better C
I supports data abstraction
I supports object-oriented programming
I supports generic programming.”

Alternatively: C++ is “an (almost upwards-compatible) extension of C


with support for: classes and objects (including multiple inheritance),
operator overloading, exceptions and templates”.
[templates are a generalised form of generics]
Much is familiar from Java, but with many subtle differences.

2 / 21
C++ fundamental types

I C++ has all the fundamental types C has


I character literals (e.g. ’a’) are now of type char
I In addition, C++ defines a new fundamental type, bool
I A bool has two values: true and false
I When cast to an integer, true→1 and false→0
I When casting from an integer, non-zero values become true and
false otherwise
I This is also available in C (since C99) via the <stdbool.h> header

3 / 21
C++ enumeration

I Unlike C, C++ enumerations define a new type; for example


enum flag {is_keyword=1, is_static=2, is_extern=4, ... }
I When allocating storage for an enumeration, you use its name; for
example: flag f = is_keyword
I Implicit type conversion is not allowed:
f = 5; //wrong f = flag(5); //right
I The maximum valid value of an enumeration is the enumeration’s
largest value rounded up to the nearest larger binary power minus one
I The minimum valid value of an enumeration with no negative values
is zero
I The minimum valid value of an enumeration with negative values is
the nearest least negative binary power

4 / 21
References

I C++ supports references, which provide an alternative name for a


variable
I Generally used for specifying parameters to functions and return
values as well as overloaded operators (more later)
I A reference is declared with the & operator; for example:
int i[] = {1,2}; int &refi = i[0];
I A reference must be initialised when it is defined
I A connection between a reference and what it refers to cannot be
changed after initialisation; for example:
refi++; //increments value referenced

5 / 21
References in function arguments
I When used as a function parameter, a referenced value is not copied;
for example:
void inc(int& i) { i++;} //bad style?
I Declare a reference as const when no modification takes place
I It can be noticeably more efficient to pass a large struct by reference
I Implicit type conversion into a temporary takes place for a const
reference but results in an error otherwise; for example:
1 float fun1(float&);
2 float fun2(const float&);
3 void test() {
4 double v=3.141592654;
5 fun1(v); //Wrong
6 fun2(v);
7 }

I Cf. Fortran call-by-reference


6 / 21
Overloaded functions
I Functions doing different things should have different names
I It is possible (and sometimes sensible!) to define two functions with
the same name
I Functions sharing a name must differ in argument types
I Type conversion is used to find the “best” match
I A best match may not always be possible:

1 void f(double);
2 void f(long);
3 void test() {
4 f(1L); //f(long)
5 f(1.0); //f(double)
6 f(1); //Wrong: f(long(1)) or f(double(1)) ?

7 / 21
Scoping and overloading

I Functions in different scopes are not overloaded; for example:

1 void f(int);
2
3 void example() {
4 void f(double);
5 f(1); //calls f(double);
6 }

I Rarely happens in practise since crossing scopes like this leads to


confusing control flow.

8 / 21
Default function arguments

I A function can have default arguments; for example:


double log(double v, double base=10.0);
I A non-default argument cannot come after a default; for example:
double log(double base=10.0, double v); //wrong
I A declaration does not need to name the variable; for example:
double log(double v, double=10.0);
I Be careful of the lexical interaction between * and =; for example:
void f(char*=0); //Wrong ’*=’ is assignment

9 / 21
Namespaces
Related data can be grouped together in a namespace:

namespace Stack { //header file void f() { //usage


void push(char); ...
char pop(); Stack::push(’c’);
} ...
}
namespace Stack { //implementation
const int max_size = 100;
char s[max_size];
int top = 0;

void push(char c) { ... }


char pop() { ... }
}

10 / 21
Using namespaces
I A namespace is a scope and expresses logical program structure
I It provides a way of collecting together related pieces of code
I A namespace without a name limits the scope of variables, functions
and classes within it to the local execution unit
I The same namespace can be declared in several source files
I The global function main() cannot be inside a namespace
I The use of a variable or function name from a different namespace
must be qualified with the appropriate namespace(s)
I The keyword using allows this qualification to be stated once, thereby
shortening names
I Can also be used to generate a hybrid namespace
I typedef can be used: typedef Some::Thing thing;
I A namespace can be defined more than once
I Allows, for example, internal and external library definitions

11 / 21
Example

1 namespace Module1 {int x;}


2

3 namespace Module2 {
4 inline int sqr(const int& i) {return i*i;}
5 inline int halve(const int& i) {return i/2;}
6 }
7

8 using namespace Module1; //"import" everything


9
10 int main() {
11 using Module2::halve; //"import" the halve function
12 x = halve(x);
13 sqr(x); //Wrong
14 }

12 / 21
Linking C and C++ code

I The directive extern "C" specifies that the following declaration or


definition should be linked as C, not C++ code:
extern "C" int f();
I Multiple declarations and definitions can be grouped in curly brackets:

1 extern "C" {
2 int globalvar; //definition
3 int f();
4 void g(int);
5 }

I Why do we need this? E.g. ‘Name mangling’ for overloaded functions.

13 / 21
User-defined types
I C++ provides a means of defining classes and instantiating objects
I Classes contain both data storage and functions which operate on
storage
I Classes have access control: private, protected and public
I Classes are created with class or struct keywords
I struct members default to public access; class to private
I The constructor syntax is a member function with the same name as
the class
I The destructor syntax is a member function with the same name as
the class, prefixed with a tilde (~)
I A constructor can be overloaded to provide multiple instantiation
methods
I Can create static (i.e. per class) member variables

14 / 21
Example

1 class Complex {
2 double re,im;
3 public:
4 Complex(double r=0.0L, double i=0.0L);
5 };
6
7 Complex::Complex(double r,double i) {
8 re=r,im=i; // deprecated initialisation-by-assignment
9 }
10
11 int main() {
12 Complex c(2.0), d(), e(1,5.0L);
13 return 0;
14 }

15 / 21
Constructors and destructors

I A default constructor is a function with no arguments (or only default


arguments)
I If no constructor is specified, the compiler will generate one
I The programmer can specify one or more constructors
I Only one constructor is called when an object is created
I There can only be one destructor
I This is called when a stack-allocated object goes out of scope or when
a heap-allocated object is deallocated with delete; this also occurs for
stack-allocated objects deallocated during exception handling (more
later).
I Stack-allocated objects with destructors are a useful way to release
resources on scope exit (similar effect as Java try-finally) – “RAII:
Resource Allocation is Initialisation”.

16 / 21
Copy constructor

I A new class instance can defined by assignment; for example;


Complex c(1,2);
Complex d = c;
I In this case, the new class instance is initialised with copies of all the
existing class’ non-static member variables; no constructor is called
I This behaviour may not always be desirable (e.g. consider a class with
a pointer as a member variable)
I In which case, define an alternative copy constructor:
Complex::Complex(const Complex&) { ... }
I If a copy constructor is not wanted, make the copy constructor a
private member function, or in C++11 use delete.

17 / 21
Assignment operator

I By default an object is copied on assignment by overwriting all


non-static member variables; for example:
1 Complex c(), d(1.0,2.3);
2 c = d; //assignment

I This behaviour may also not be desirable


I The assignment operator (operator=) can be defined explicitly:
1 Complex& Complex::operator=(const Complex& c) {
2 ...
3 }

18 / 21
Constant member functions

I Member functions can be declared const


I Prevents object members being modified by the function:
1 double Complex::real() const {
2 return re;
3 }

I Logically gives const Complex *this instead of Complex *this

19 / 21
Arrays and the free store
I An array of class objects can be defined if a class has a default
constructor
I C++ has a new operator to place items on the heap:
Complex* c = new Complex(3.4);
I Items on the heap exist until they are explicitly deleted:
delete c;
I Since C++ (like C) doesn’t distinguish between a pointer to a single
object and a pointer to an the first element of an array of objects,
array deletion needs different syntax:
1 Complex* c = new Complex[5];
2 ...
3 delete[] c; // Cannot use "delete" here, only "delete[]"
I When an object is deleted, the object destructor is invoked. When an
array is deleted, the object destructor is invoked on each element
I The C++ standard library provides std::vector or std::array, so
raw arrays are rarely used
20 / 21
Exercises
1. Write an implementation of a class LinkList which stores zero or
more positive integers internally as a linked list on the heap. The
class should provide appropriate constructors and destructors and a
method pop() to remove items from the head of the list. The method
pop() should return -1 if there are no remaining items. Your
implementation should override the copy constructor and assignment
operator to copy the linked-list structure between class instances. You
might like to test your implementation with the following:
1 int main() {
2 int test[] = {1,2,3,4,5};
3 LinkList l1(test+1,4), l2(test,5);
4 LinkList l3=l2, l4;
5 l4=l1;
6 printf("%d %d %d\n",l1.pop(),l3.pop(),l4.pop());
7 return 0;
8 }
Hint: heap allocation & deallocation should occur exactly once!
21 / 21

You might also like