Auto - Storage Class: (Int Count Auto Int Month )
Auto - Storage Class: (Int Count Auto Int Month )
a C Program.
auto
register
static
extern
{
int Count;
auto int Month;
}
The example above defines two variables with the same storage class. auto can only be used
within functions, i.e. local variables.
register is used to define local variables that should be stored in a register instead of RAM.
This means that the variable has a maximum size equal to the register size (usually one
word) and cant have the unary '&' operator applied to it (as it does not have a memory
location).
{
register int Miles;
}
Register should only be used for variables that require quick access - such as counters. It
should also be noted that defining 'register' goes not mean that the variable will be stored in
a register. It means that it MIGHT be stored in a register - depending on hardware and
implimentation restrictions.
static is the default storage class for global variables. The two variables below (count and
road) both have a static storage class.
{
printf("%d\n", Road);
}
static variables can be 'seen' within all functions in this source file. At link time, the static
variables defined here will not be seen by the object modules that are brought in.
static can also be defined within a function. If this is done the variable is initalised at run time
but is not reinitalized when the function is called. This inside a function static variable retains
its value during vairous calls.
void func(void);
main()
{
while (count--)
{
func();
}
i is 6 and count is 9
i is 7 and count is 8
i is 8 and count is 7
i is 9 and count is 6
i is 10 and count is 5
i is 11 and count is 4
i is 12 and count is 3
i is 13 and count is 2
i is 14 and count is 1
i is 15 and count is 0
NOTE : Here keyword void means function does not return anything and it does not take any
parameter. You can memoriese void as nothing. static variables are initialized to 0
automatically.
There is one more very important use for 'static'. Consider this bit of code.
char *func(void);
main()
{
char *Text1;
Text1 = func();
}
char *func(void)
{
char Text2[10]="martin";
return(Text2);
}
Now, 'func' returns a pointer to the memory location where 'text2' starts BUT text2 has a
storage class of 'auto' and will disappear when we exit the function and could be overwritten
but something else. The answer is to specify
The storage assigned to 'text2' will remain reserved for the duration if the program.
extern is used to give a reference of a global variable that is visible to ALL the program files.
When you use 'extern' the variable cannot be initalized as all it does is point the variable
name at a storage location that has been previously defined.
When you have multiple files and you define a global variable or function which will be used
in other files also, then extern will be used in another file to give reference of defined
variable or function. Just for understanding extern is used to decalre a global variable or
function in another files.
File 1: main.c
int count=5;
main()
{
write_extern();
}
File 2: write.c
void write_extern(void);
void write_extern(void)
{
printf("count is %i\n", count);
}
Count in 'main.c' will have a value of 5. If main.c changes the value of count - write.c will see
the new value
Singleton Class:
A: There are several ways of creating a singleton class. The most simple approach is
shown below:
Code:
class CMySingleton
{
public:
static CMySingleton& Instance()
{
static CMySingleton singleton;
return singleton;
}
Q: Can I extend the singleton pattern to allow more than one instance?
A: The general purpose of the singleton design pattern is to limit the number of
instances of a class to only one. However, the pattern can be extended by many ways to
actually control the number of instances allowed. One way is shown below...
Code:
class CMyClass
{
private:
CMyClass() {} // Private Constructor
public:
~CMyClass(); // Public Destructor
Here we declare our constructor/s as private, thus denying direct creation of the
class.
A static function CreateInstance that creates the class indirectly for us.
Two static members, one holding the current number of instances, another one
the maximum allowed.
Note: We have to declare at least one constructor (private - of course), else
direct creation will be possible.
Code:
int CMyClass::nCount = 0;
int CMyClass::nMaxInstance = 1; // When maxInstance is 1, we have a
pure singleton class
CMyClass::~CMyClass()
{
--nCount; // Decrement number of instances
}
CMyClass* CMyClass::CreateInstance()
{
CMyClass* ptr = NULL;
Everytime an instance is created, the count is incremented, and when the object
is deleted, the destructor is invoked, and the count is decremented.
Since, the objective is to limit the number of instances, we allow direct
destruction of object.
As a special case, when 'maxInstance' is 1, we have a pure singleton class.
class AB {
public:
virtual void f() = 0;
};
Function AB::f is a pure virtual function. A function declaration cannot have both a pure
specifier and a definition. For example, the compiler will not allow the following:
struct A {
virtual void g() { } = 0;
};
You cannot use an abstract class as a parameter type, a function return type, or the type of an
explicit conversion, nor can you declare an object of an abstract class. You can, however,
declare pointers and references to an abstract class. The following example demonstrates this:
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { }
};
// Error:
// Class A is an abstract class
// A g();
// Error:
// Class A is an abstract class
// void h(A);
A& i(A&);
int main() {
// Error:
// Class A is an abstract class
// A a;
A* pa;
B b;
// Error:
// Class A is an abstract class
// static_cast<A>(b);
}
Class A is an abstract class. The compiler would not allow the function declarations A g() or
void h(A), declaration of object a, nor the static cast of b to type A.
Virtual member functions are inherited. A class derived from an abstract base class will also
be abstract unless you override each pure virtual function in the derived class.
For example:
class AB {
public:
virtual void f() = 0;
};
class D2 : public AB {
void g();
};
int main() {
D2 d;
}
The compiler will not allow the declaration of object d because D2 is an abstract class; it
inherited the pure virtual function f()from AB. The compiler will allow the declaration of
object d if you define function D2::g().
Note that you can derive an abstract class from a nonabstract class, and you can override a
non-pure virtual function with a pure virtual function.
You can call member functions from a constructor or destructor of an abstract class.
However, the results of calling (directly or indirectly) a pure virtual function from its
constructor are undefined. The following example demonstrates this:
struct A {
A() {
direct();
indirect();
}
virtual void direct() = 0;
virtual void indirect() { direct(); }
};
The default constructor of A calls the pure virtual function direct() both directly and
indirectly (through indirect()).
The compiler issues a warning for the direct call to the pure virtual function, but not for the
indirect call.