CSIS 123A Lecture 7

29
CSIS 123A Lecture 7 Static variables, destructors, & namespaces

description

CSIS 123A Lecture 7. Static variables, destructors, & namespaces. Static variables. Maintains its value among different function calls Declared on heap Declared using static key word static int myInt;. Example. int main() { for(int i = 0; i < 10; i++) updateStatic(); } - PowerPoint PPT Presentation

Transcript of CSIS 123A Lecture 7

Page 1: CSIS 123A Lecture 7

CSIS 123A Lecture 7

Static variables, destructors, & namespaces

Page 2: CSIS 123A Lecture 7

Static variables

• Maintains its value among different function calls– Declared on heap

• Declared using static key word– static int myInt;

Page 3: CSIS 123A Lecture 7

Exampleint main(){ for(int i = 0; i < 10; i++)

updateStatic();

}void updateStatic(){static in myInt = 0;

cout << ++myInt << endl;}

myInt retains its value through each function call. The above code will print 0 - 9

Page 4: CSIS 123A Lecture 7

Static class variables

• Allows each instance of the class to share a variable.– Actually doesn’t require an instance of the

class to exist.– Functions can also be static

• Should access through class name not instance– myClass::someFunction();– Not myClass mc;– mc.someFunctions

Page 5: CSIS 123A Lecture 7

More static classes

• you cannot initialize the static class member inside of the class. – In fact, if you decide to put your code in a

header file, you cannot even initialize the static variable inside of the header file;

• do it in a .cpp file instead. • You are required to initialize the static class

member or it will not be in scope. (The syntax is a bit different: "type class_name::static_variable = value".)

Page 6: CSIS 123A Lecture 7

Exampleclass CSquare{public:

static double Side;CSquare() {};void setSide(double S) { Side = S; }double getSide() { return Side; }double Area() { return Side * Side; }

};

double CSquare::Side = 30.65;int main(){

CSquare Sqr;

cout << "Square Characteristics";cout << "\nSide: " << CSquare::Side;cout << "\nArea: " << Sqr.Area() << endl;

Sqr.setSide(44.28);

cout << "\nSquare Characteristics";cout << "\nSide: " << CSquare::Side;cout << "\nArea: " << Sqr.Area();

cout << "\n";return 0;

}

Page 7: CSIS 123A Lecture 7

Singleton Patterns• Ensures that a class has only one instance

– Provide a global point of access to the class

• Many situations in which a singleton object is necessary– a GUI application must have a single mouse– an active modem needs one and only one

telephone line– an operating system can only have one window

manager– A PC is connected to a single keyboard

Page 8: CSIS 123A Lecture 7

Design Considerations

• Using a global object ensures that the instance is easily accessible but it doesn't keep you from instantiating multiple objects.– Our addressBook for example

• you can still create a local instance of the same class in addition to the global one.

– Singleton patterns provides an elegant solution to this problem by making the class itself responsible for managing its sole instance.

• The sole instance is an ordinary object of its class, but that class is written so that only one instance can ever be created.

– you provide a global point of access to that instance.• hides the operation that creates the instance behind a static

member function. – This member function, traditionally called Instance(), returns a

pointer to the sole instance.

Page 9: CSIS 123A Lecture 7

Example

class Singleton { public: static Singleton* Instance(); Singleton(); Singleton(const Singleton&); Singleton& operator= (const Singleton&);private: static Singleton* pinstance; };

The class declares a private static pointer to its instance, pinstanceWhen the static function Instance() is called for the first time, it creates the sole instance, assigns its address to pinstance, and returns that address.Subsequent calls, Instance() will merely return that address.

Page 10: CSIS 123A Lecture 7

Example ContinuedSingleton* Singleton::pinstance = 0;// initialize pointer Singleton* Singleton::Instance () { if (pinstance == 0) // is it the first call? { pinstance = new Singleton; // create sole instance } return pinstance; // address of sole instance } Singleton::Singleton() { //... perform necessary instance initializations }

Page 11: CSIS 123A Lecture 7

Inline Functions

• Treated like a macro– Code substitution happens (Function not called)

• Compiler will replace function call with actual code for the function

• Many compilers will decide– If inline code is too big, compiler will not make it inline

• Functions are declared with the keyword inline– inline int add(int x,int y)

Page 12: CSIS 123A Lecture 7

More Inline

• Inline functions should be used for small pieces of code

• Advantage is code executes faster• Disadvantage: makes your code larger

inline int add(int x,int y)    {        return x+y;    }

Page 13: CSIS 123A Lecture 7

Destructors

• The opposite of a constructor– Are less complicated than constructors– You don't call them explicitly (they are called

automatically for you)• There's only one destructor for each object.

– The name of the destructor is the name of the class, preceeded by a tilde (~).

– called when the object of a class goes out of scope

Page 14: CSIS 123A Lecture 7

Exampleclass Example     {       private:         int x; //Data member          int y; // Data member        public:          Example() //Constructor for the C++ tutorial          {              x = 0;             y = 0;         }       ~Example() //destructor        { }       int Add()       {          return x+y;      }};

Page 15: CSIS 123A Lecture 7

Namespaces

• Allow you to group a set of global classes, objects and/or functions under a name. – They serve to split the global scope in sub-

scopes known as namespaces – namespaces use the following form:

namespace identifier {     namespace-body }

Page 16: CSIS 123A Lecture 7

Namespaces II• Where identifier is any valid identifier and

namespace-body is the set of classes, objects and functions that are included within the namespace .

namespace general {   int a, b;}

Page 17: CSIS 123A Lecture 7

Namespaces III

• a and b are normal variables integrated within the general namespace .– In order to access these variables from

outside the namespace you have to use the scope operator :: .

– general::a general::b

Page 18: CSIS 123A Lecture 7

Namespaces IV

• Useful in case there is a possibility that a global object or function has the same name as another one,– causing a redefinition error. For example:

Page 19: CSIS 123A Lecture 7

Example// namespaces#include <iostream> using namespace std; namespace first{int var = 5;}namespace second{double var = 3.1416;}int main (){cout << first::var << endl;cout << second::var << endl;return 0;}

Page 20: CSIS 123A Lecture 7

Using Namespaces

• The using directive followed by namespace serves to associate the present nesting level with a certain namespace so that the objects and functions of that namespace can be accesible directly as if they were defined in the global scope. Its utilization follows this prototype:

• using namespace identifier ;

Page 21: CSIS 123A Lecture 7

Example using// using namespace example#include <iostream>using namespace std;namespace first{int var = 5;}namespace second{ double var = 3.1416;}int main () { using namespace second; cout << var << endl; cout << (var*2) << endl; return 0;}

Page 22: CSIS 123A Lecture 7

More Namespace

• You have to consider that the sentence using namespace has validity only in the block in which it is declared (block scope)

• Used in the global scope. For example, if we had intention to first use the objects of a namespace and then those of another one we could do something similar to the next example

Page 23: CSIS 123A Lecture 7

#include <iostream>using namespace std; namespace first{int var = 5;}namespace second{double var = 3.1416;}int main (){

   {      using namespace first;      cout << var << endl;   }

   {      using namespace second;      cout << var << endl;   }return 0;}

Page 24: CSIS 123A Lecture 7

Alias Definition

• You can also define alternative names for namespaces that already exist. It is done as follows

• namespace new_name = current_name ;

Page 25: CSIS 123A Lecture 7

Namespace std

• The use of std is a recent addition to the language. – It is almost as recent as the ANSI standard itself

(1997) and many older compilers do not comply with this rule.

– Almost all compilers allow the use of the traditional header files (like iostream.h , stdlib.h , etc),

• Can be used just as you would namespaces. • The ANSI standard has completely redesigned these libraries

taking advantage of the templates feature and following the rule to declare all the functions and variables under the namespace std .

Page 26: CSIS 123A Lecture 7

std II

• The standard has specified new names for these "header" files.– Basically using the same name for C++

specific files, but without the ending .h . • iostream.h becomes iostream

• If we use the ANSI-C++ compliant include files we have to bear in mind that all the functions, classes and objects will be declared under the std namespace.

Page 27: CSIS 123A Lecture 7

Example std// ANSI-C++ compliant hello world#include <iostream>

int main () {std::cout << "Hello world in ANSI-C++\n";return 0;}

// ANSI-C++ compliant hello world (II)#include <iostream>using namespace std;

int main () {cout << "Hello world in ANSI-C++\n";return 0;}

Page 28: CSIS 123A Lecture 7

Command Line Arguments

• Allows you to pass information into program through main– Two arguments to main

• Int main(int argc, char argv[][]) or• Int main(int argc, char **argv)

– argc is the argument count• It starts at one. argc == 0 would mean no arguments

– argv is an array of cstrings (2D array of chars)• Contains information passed• argv[0] is name of program

Page 29: CSIS 123A Lecture 7

Parsing Command Line Arguments

• Passing data is simple– From command line

• cmdArgs arg1 arg2• argv[0] == “cmdArgs.exe”• argv[1] == “arg1”

argv[2] == “arg2”

// cmdArgs.exe#include <iostream> using namespace std; int main(int argc, char **argv) {    cout << "argc = " << argc << endl;    for(int i = 0; i < argc; i++)       cout << "argv[" << i << "] = " << argv[i] << endl;    return 0; }