name lookup (name control)
DESCRIPTION
Name lookup (name control). Variables Variable names are searched for in the below order. 1. Locally 2. Class-scope 3. File scope (global). Name lookup (name control). void fun(int x) { { int x = 5; coutTRANSCRIPT
1
Name lookup (name control) Variables
Variable names are searched for in the below order.
1. Locally
2. Class-scope
3. File scope (global)
2
Name lookup (name control)
void fun(int x)
{
{
int x = 5;
cout << x << endl;
}
cout << x << endl;
}
3
Name lookup (name control) Functions Name to match a function is searched
for in the below order.
1. Class-scope (if invoked from an
operation belonging to a class)
2. File-scope
4
Name lookup (name control) Example class-scope
void X::fun() { f(); }
class X
{ //. . .
void f(); // name match
};
The scope operator :: makes it possible to access the desired scope
5
Name lookup (name control) The search for a name match is always
done before the access control.
void f(){. . .} //global function
class X : public B {. . .};
class B
{
//. . .
private:
void f(); // name match
};
void X::fun(){ f(); }
6
Class scope (name control) Enumerations, shared data, and
functions
class Date
{
public:
enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN };
static int days_per_month[12]; //shared data
static bool is_leap(int); //shared function
//. . .
}
7
Class scope (name control) Declaration of an array with constant size in a class
class Stack
{
//. . .
private:
static const int SIZE = 20; // new proposed feature, still an ERROR with most compilers
static const int SIZE; // OK, but this still does not help array initialization
enum { SIZE = 20 }; // This is the trick
int array[SIZE];
}
const int Stack :: SIZE = 20; //implementation
//initialization
8
Namespaces (name control)
//Declarations
namespace Vendor_A_Containers {
template<class T> class List { . . . };
template<class T> class Queue { . . . };
. . .
}
//Implementation
namespace Vendor_A_Containers {
template<class T> T Queue<T>::remove() { . . . };
template<class T> int Queue<T>::length() const { . . . };
. . .
}
9
Namespaces (name control) Using namespaces//Method 1
//exhaustive
Vendor_A_Containers::Queue<Employee> q;
//The programmer defines an alias.
namespace Cont = Vendor_A_Containers;
Cont::Queue<Employee> q; //BETTER!
10
Namespaces (name control)
Method nr 2
class Bank
{
using Vendor_A_Containers :: Queue;
// . . .
private:
Queue<Customer> waitingQueue;
. . .
}; A using declaration can be put into any scope
11
Namespaces (name control)
#include <stdlib.h> //deprecated To provide backward compatibility with the C
standard library, the <xxx.h> naming is still supported, although it is deprecated.
Use the newer <cxxx>, or <xxx> instead.
#include <cstdlib> //OK
The <cxxx> is used for the old c-headers and the <xxx> is used for the c++-headers.
12
An example//Namespace.h
#ifndef _RS_NAMESPACE_
#define _RS_NAMESPACE_
namespace RS_namespace
{
template <class T>
class List
{
template <class T> class Nod;
public:
typedef Nod<T> nod;
typedef Nod* nod_ptr;
List();
~List();
void ListInsert(T);
//. . .
private:
template <class T>
class Nod
{ public:
T data;
Nod<T>* next;
};
nod_ptr head;
int size;
};
} //end RS_namespace
#endif
13
//List.cpp
#include "RS_namespace.h"
namespace RS_namespace {
//pre: none
//post:a list object is created and initiated
template <class T> List<T>::List()
{
size=0; //sätter storlek på listan till 0
head=NULL;
}
//pre: none
//post:The list object is removed, and memory is returned
template <class T> List<T>::~List()
{
while (!ListIsEmpty())
ListDelete(1);
}
//pre: none
//post:An element is inserted as the first element of the list
template <class T> void List<T>::ListInsert(T newdata)
{
size++;
nod_ptr newptr=new Nod;
newptr->data=newdata;
newptr->next=head; //sätt alltid in först i listan
head=newptr;
}
} //end namespace
14
//main.cpp
#include "RS_namespace.h"
void main()
{
//using just List from RS_namespace
using RS_namespace::List;
//Induce the whole namespace ”RS_namespace”
using namespace RS_namespace;
List<int> myList;
}
15
Access control (name control) Declarations and definitions Example definitions
int x;
Employee lars("Lars");
int square(int x){ return x*x; }
Example declarations
extern int x;
extern Employee lars;
int square();
class Date;
enum Color;
16
Access control (name control) Public, private and protected public
Access is allowed from all clients.
protected Access is allowed from the class itself,
subclasses and friends.
Private Access is allowed from the class itself and
friends.
17
Access control (name control)
Friends - (use with care) A class can declare a function or another class as a friend.
This gives the declared friend(s) total access to the class members.
class Link
{
friend class List;
friend class Queue;
private:
Link() : _next=0 {};
int _info;
Link* _next;
}; When is this useful?
18
Access control Friends (cont...)
The friend keyword is not only telling you that this function is a friend it is also implicitly telling you that it is not a member.
The friend keyword can only be used within a class-definition.
19
Design issues for name control Don’t pollute the global namespace with global
variables. Eliminate them by making them shared data
members of a class. Eliminate global functions by making them
shared class functions. Use a nested class to define a class that are
implementation specific to the class that use it Think carefully before taking a decision about
making a function or class a friend. Do not use protected data!
20
Objects An object is characterized by its:
State Operations Identity
What is a class?
What is object oriented programming?
21
Memory handling A C++ program can allocate memory in
three memory areas:
The run time stack (Automatic storage)
Static storage The heap memory, also called free
storage or dynamic memory.
22
Constructors (memory handling) Every class has four special member
functions: The default constructor The copy-constructor The destructor The assignment operator
23
Generation of default cons.class File
{
private:
string path;
int mode;
public:
File(const string& file_path, int open_mode);
~File();
};
//error, array requires default
//constructor File
File folder1[10];
// error, f2[1] still requires
// default constructor
File folder2[2] = { File("f1", 1)};
//OK, fully nitialized array
folder3[3] = { File("f1", 1), File("f2",2), File("f3",3) };
24
Explicit constructorsclass string
{
public:
string();
//constructors and implicit
//conversion operators
string(int size);
string(const char *);
~string();
private:
int size;
int capacity;
char *buff;
};
25
Explicit constructors What happens in the program below?
int main()
{
string s = "hello"; //OK, convert a
//C-string into a string object
int ns = 0;
s = 1; // 1 oops, programmer
//intended to write ns = 1
}
26
Explicit constructors Solution
class string
{
public:
//block implicit conversion
explicit string(int size);
//implicit conversion
string(const char *);
~string();
};
27
Explicit constructors Solution (cont..)
int main()
{
string s = "hello"; //OK, convert a
//C-string into a string object
int ns = 0;
s = 1; // compile time error, this
//time the compiler catches
//the typo
}
28
Initializing class members There are four different cases to consider
when initializing class members in the constructor.
Initialization of const members. Initialization of alias (reference) members. Initialization of base class members through a
subclass, by sending arguments to the base class constructor.
Initialization of member objects.
In the three first cases an initializer list is mandatory. The fourth case is optional.
29
Copy constructors Why have one?
To copy objects who differ only in identity.
To copy arguments and return values to and from functions, using call-by-value.
When do you absolutely need to define one? All classes with a non trivial
destructor need both a user defined copy-constructor and a user defined assignment operator.
30
Destructors Why have a destructor?
To free resources.
When do I have to define it explicitly? Whenever there is dynamic memory
allocation involved.
Why have a virtual destructor? Whenever the class is a potential
base class.
31
The assignment operator Why have one?
To be able to control what happens when assignment takes place.
When do I need to define one? All classes with a non trivial
destructor need a user defined assignment operator.
Generic form
C& C::operator=(const C&);
32
The assignment operator The assigment operator and the
destructor.// What happens?
List a:
a.insert(. . .);
//. . .
List b;
b.insert(. . .);
//. . .
a = b;
// b goes out of scope
33
The assignment operator
Two problems:
The list a is not removed.
The list b is removed twice!
34
Common factors ... … between the destructor, the copy constructor and
the assignment operator
void List::copy(const List& b)
{
//kod för att kopiera
}
void List::free()
{
//kod för att frigöra minnet
}
List::List(const List& b)
{
copy(b);
}
35
Common factors . . .
List::~List()
{
free();
}
const List& List::operator=( const List& b )
{
if( this != &b)
{
free();
copy(b);
}
return *this;
}