Вы находитесь на странице: 1из 12

1.

It is okay to convert a pointer from derived class to its base class

An object of a derived class is a kind of the base class. Therefore the conversion
from a derived class pointer to a base class pointer is perfectly safe, and
happens all the time. For example, if I am pointing at a car, I am in fact pointing
at a vehicle, so converting a Car* to a Vehicle* is perfectly safe and normal:

void f(Vehicle* v);


void g(Car* c) { f(c); } // Perfectly safe; no cast
2. What's the difference between public, private, and protected?

• A member (either data member or member function) declared in a private section


of a class can only be accessed by member functions and friends of that class
• A member (either data member or member function) declared in a protected
section of a class can only be accessed by member functions and friends of that
class, and by member functions and friends of derived classes
• A member (either data member or member function) declared in a public section
of a class can be accessed by anyone

3. References

An alias (an alternate name) for an object. References are frequently used for
pass-by-reference:
void swap(int& i, int& j) {

int tmp = i;
i = j;
j = tmp;
}

int main()
{
int x, y;
...
swap(x,y);
...
}
Here i and j are aliases for main's x and y respectively. In other words, i is x —
not a pointer to x, nor a copy of x, but x itself. Anything you do to i gets done to x, and
vice versa. OK. That's how you should think of references as a programmer. Now, at the
risk of confusing you by giving you a different perspective, here's how references are
implemented. Underneath it all, a reference i to object x is typically the machine address
of the object x. But when the programmer says i++, the compiler generates code that
increments x. In particular, the address bits that the compiler uses to find x are not
changed. A C programmer will think of this as if you used the C style pass-by-pointer,
with the syntactic variant of (1) moving the & from the caller into the callee, and (2)
eliminating the *s. In other words, a C programmer will think of i as a macro for (*p),
where p is a pointer to x (e.g., the compiler automatically dereferences the underlying
pointer; i++ is changed to (*p)++; i = 7 is automatically changed to *p = 7).
4. How can you reseat a reference to make it refer to a different object?

you can not reseat a reference

Unlike a pointer, once a reference is bound to an object, it can not be "reseated" to


another object. The reference itself isn't an object (it has no identity; taking the address
of a reference gives you the address of the referent; remember: the reference is its
referent). In that sense, a reference is similar to a const pointer such as int* const p

References are usually preferred over pointers whenever you don't need "reseating".
This usually means that references are most useful in a class's public interface.
References typically appear on the skin of an object, and pointers on the inside.

4. What does "Fred const& x" mean?

It means x aliases a Fred object, but x can't be used to change that Fred object.

Read it right-to-left: "x is a reference to a constant Fred."


For example, if class Fred has a const member function called inspect(), saying
x.inspect() is OK. But if class Fred has a non-const member function called mutate(),
saying x.mutate() is an error (the error is caught by the compiler; no run-time tests are
done, which means const doesn't slow your program down).

6. Does "Fred& const x" make any sense?

No, To find out what the above declaration means, you have to read it right-to-left. Thus
"Fred& const x" means "x is a const reference to a Fred". But that is redundant, since
references are always const. You can't reseat a reference. Never. With or without the
const.

7. What's the order that local objects are destructed?

In reverse order of construction: First constructed, last destructed.


In the following example, b's destructor will be executed first, then a's destructor:
void userCode()
{
Fred a;
Fred b;
...
}
You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It
never takes any parameters, and it never returns anything.
8. Why can't I initialize my static member data in my constructor's
initialization list?

Because you must explicitly define your class's static data members.
Fred.h:
class Fred {
public:
Fred();
...
private:
int i_;
static int j_;
};
Fred.cpp (or Fred.C or whatever):
Fred::Fred()
: i_(10) // OK: you can (and should) initialize member data this way
, j_(42) // Error: you cannot initialize static member data like this
{
...
}
// You must define static data members this way:
int Fred::j_ = 42;

9. How do you tell the compiler to make a non-member function inline?

When you declare an inline function, it looks just like a normal function:
void f(int i, char c);
But when you define an inline function, you prepend the function's definition with
the keyword inline, and you put the definition into a header file:
inline
void f(int i, char c)
{
...
}
Note: It's imperative that the function's definition (the part between the {...}) be
placed in a header file, unless the function is used only in a single .cpp file. In
particular, if you put the inline function's definition into a .cpp file and you call it from
some other .cpp file, you'll get an "unresolved external" error from the linker.

How do you tell the compiler to make a member function inline?


When you declare an inline member function, it looks just like a normal member
function:
class Fred {
public:
void f(int i, char c);
};
But when you define an inline member function, you prepend the member
function's definition with the keyword inline, and you put the definition into a header file:
inline
void Fred::f(int i, char c)
{
...
}
It's usually imperative that the function's definition (the part between the {...}) be
placed in a header file. If you put the inline function's definition into a .cpp file, and if it is
called from some other .cpp file, you'll get an "unresolved external" error from the linker.

Is there another way to tell the compiler to make a member function inline?
Yep: define the member function in the class body itself:
class Fred {
public:
void f(int i, char c)
{
...
}
};

PREVIOUS CPP FILE

Function members in classes

Ordinary member functions :

These are ordinary functions defined with a return type and parameters. The return type can
also be void. The special trait about member functions is they can access the private/protected
data members of their class and manipulate them. No external functions can access the
private/protected data members of a class.

Constructors:

Constructors in C++ are special member functions of a class. They have the same name as the
Class Name. There can be any number of overloaded constructors inside a class, provided they
have a different set of parameters. There are some important qualities for a constructor to be
noted.

• Constructors have the same name as the class.


• Constructors do not return any values
• Constructors are invoked first when a class is initialized. Any initializations for the class
members, memory allocations are done at the constructor.
Destructors:

Destructors in C++ also have the same name, except for the fact that they are preceded by a '~'
operator. The destructors are called when the object of a class goes out of scope. It is not
necessary to declare a constructor or a destructor inside a class. If not declared, the compiler will
automatically create a default one for each. If the constructor/destructor is declared as private,
then the class cannot be instantiated.

Access Level:

The classes in C++ have 3 important access levels. They are Private, Public and Protected.
The explanations are as follows.

Private:

The members are accessible only by the member functions or friend functions.

Protected:

These members are accessible by the member functions of the class and the classes which are
derived from this class.

Public:

Accessible by any external member.

Function overloading

Function overloading is the practice of declaring the same function with different
signatures. The same function name will be used with different number of parameters and
parameters of different type. But overloading of functions with different return types are not
allowed.

When a function is declared inline, the function is expanded at the calling block. The
function is not treated as a separate unit like other normal functions.
But a compiler is free to decide, if a function qualifies to be an inline function. If the inline
function is found to have larger chunk of code, it will not be treated as an inline function, but as
like other normal functions.
Inline functions are treated like macro definitions by the C++ compiler.

In fact, the keyword inline is not necessary. If the function is defined with its body directly
and the function has a smaller block of code, it will be automatically treated as inline by the
compiler.
Static Functions

Static data types can be accessed without instantiation of the class in C++. This is
applicable for static functions also.
The differences between a static member function and non-static member functions are
as follows.

• A static member function can access only static member data, static member functions
and data and functions outside the class. A non-static member function can access all of
the above including the static data member.
• A static member function can be called, even when a class is not instantiated, a non-
static member function can be called only after instantiating the class as an object.
• A static member function cannot be declared virtual, whereas a non-static member
functions can be declared as virtual
• A static member function cannot have access to the 'this' pointer of the class.

The static member functions are not used very frequently in programs. But nevertheless, they
become useful whenever we need to have functions which are accessible even when the class is
not instantiated.

The this pointer is used as a pointer to the class object instance by the member function. The
address of the class instance is passed as an implicit parameter to the member functions.
The sample below, in this c++ Tutorial shows how to use it. It is a common knowledge
that C++ keeps only one copy of each member function and the data members are
allocated memory for all of their instances. This kind of various instances of data are
maintained use this pointer. Look at the sample below, in this c++ Tutorial.

C++ Tutorial - important notes on this pointer:

• this pointer stores the address of the class instance, to enable pointer access of the
members to the member functions of the class.
• this pointer is not counted for calculating the size of the object.
• this pointers are not accessible for static member functions.
• this pointers are not modifiable.

friend

A class can allow non-member functions and other classes to access its own private
data, by making them as friends. This part of C++ tutorial essentially gives two important points.

• Once a non-member function is declared as a friend, it can access the private data of the
class
• similarly when a class is declared as a friend, the friend class can have access to the
private data of the class which made this a friend
#include < iostream.h >
class CPP_Tutorial
{
int private_data;
friend class friendclass;
public:
CPP_Tutorial()
{
private_data = 5;
}
};
class friendclass
{
public:
int subtractfrom(int x)
{
CPP_Tutorial var2;
return var2.private_data - x;
}
};
int main()
{
friendclass var3;
cout << "Added Result for this C++ tutorial: "<< var3.subtractfrom(2)<
} The output of the above C++ Tutorial sample will be
Subtracted Result for this C++ tutorial: 3

inheritance

Creating or deriving a new class using another class as a base is called inheritance in C+
+. The new class created is called a Derived class and the old class used as a base is called a
Base class in C++ inheritance terminology.
The derived class will inherit all the features of the base class in C++ inheritance. The
derived class can also add its own features, data etc., It can also override some of the features
(functions) of the base class, if the function is declared as virtual in base class.
C++ inheritance is very similar to a parent-child relationship. When a class is inherited
all the functions and data member are inherited, although not all of them will be accessible by the
member functions of the derived class. But there are some exceptions to it too.
Some of the exceptions to be noted in C++ inheritance are as follows.

• The constructor and destructor of a base class are not inherited


• the assignment operator is not inherited
• the friend functions and friend classes of the base class are also not inherited.

What is a Virtual Function?


A virtual function is a member function of a class, whose functionality can be over-ridden
in its derived classes. It is one that is declared as virtual in the base class using the
virtual keyword. The virtual nature is inherited in the subsequent derived classes and the
virtual keyword need not be re-stated there. The whole function body can be replaced
with a new set of implementation in the derived class.

The difference between a non-virtual member function and a virtual member


function is, the non-virtual member functions are resolved at compile time.

Virtual Constructors and Destructors

A constructor cannot be virtual because at the time when the constructor is invoked the
virtual table would not be available in the memory. Hence we cannot have a virtual
constructor.
A virtual destructor is one that is declared as virtual in the base class and is used
to ensure that destructors are called in the proper order. It is to be remembered that
destructors are called in the reverse order of inheritance. If a base class pointer points to
a derived class object and we some time later use the delete operator to delete the
object, then the derived class destructor is not called.

#include <iostream.h>
class base
{
public:
virtual void display()
{
cout<<”\nBase”;
}
};
class derived : public base
{
public:
void display()
{
cout<<”\nDerived”;
}
};

void main()
{

base *ptr = new derived();


ptr->display();
}
In the above example, the pointer is of type base but it points to the derived class
object. The method display() is virtual in nature. Hence in order to resolve the virtual
method call, the context of the pointer is considered, i.e., the display method of the
derived class is called and not that of the base. If the method was non virtual in nature,
the display() method of the base class would have been called.

Virtual Constructors and Destructors

A constructor cannot be virtual because at the time when the constructor is invoked the
virtual table would not be available in the memory. Hence we cannot have a virtual
constructor.
A virtual destructor is one that is declared as virtual in the base class and is used
to ensure that destructors are called in the proper order. It is to be remembered that
destructors are called in the reverse order of inheritance. If a base class pointer points to
a derived class object and we some time later use the delete operator to delete the
object, then the derived class destructor is not called. Refer to the code that follows:
#include <iostream.h>
class base
{
public:
~base()
{

}
};

class derived : public base


{
public:
~derived()
{
}
};

void main()
{

base *ptr = new derived();


// some code
delete ptr;
}
In this case the type of the pointer would be considered. Hence as the pointer is
of type base, the base class destructor would be called but the derived class destructor
would not be called at all. The result is memory leak. In order to avoid this, we have to
make the destructor virtual in the base class. This is shown in the example below:
#include <iostream.h>
class base
{
public:
virtual ~base()
{

}
};

class derived : public base


{
public:
~derived()
{

};

void main()
{

base *ptr = new derived();


// some code
delete ptr;
}

Two very important concepts in object-oriented programming are overriding and


overloading. Overloading is about creating multiple methods with the same name, but
different signatures, in the same scope. Overriding is about changing the behavior of a
certain method in the child class from the way it is behaving in the parent class.

Hashtable is synchronized means it's therad safe where as hashmap is not and
hash table can't store null value hashmap can store null values. HashTable is thread
safe is because it makes lock in it when it executes get() or put() methods. It is good one
when you use the data in an multi-threading application. You may try use hashmap
inside synchronized block.

Arrays can be expected to have the fastest access (primitives functions) and
least amount of memory usage. However they are fixed in size.

If you need something that dynamically resizes, a collection object is more


useful.
These days, ArrayList is referred over Vector because Vector is thread-safe and
that's extra overhead (unless you actually [i]need/[i] to be thread-safe.

if you have the index, using a standard array is faster in all cases where you can
fit the whole array in memory.

Maps are good for associated arrays (e.g. where the index is a string), for sparse
arrays (where only a few elements are used, but the index range is large), etc.

Using maps for sparse arrays generally uses (much) less memory than a normal
array.

Placement new
What is the "placement new" operator in C++?
Placement new
Operator new allocates memory from the heap, on which an object is constructed.
Standard C++ also supports placement new operator, which constructs an object on a
pre-allocated buffer. This is useful when building a memory pool, a garbage collector or
simply when performance and exception safety are paramount (there's no danger of
allocation failure since the memory has already been allocated, and constructing an
object on a pre-allocated buffer takes less time):
void placement() {

char *buf = new char[1000]; //pre-allocated buffer


string *p = new (buf) string("hi"); //placement new
string *q = new string("hi"); //ordinary heap allocation
cout<c_str()<c_str();<

Advantages of new over malloc


1. new invokes the constructor of the object created. malloc does not.
2. new does not need an explicit typecasting as in the case of malloc
[int *p=(int *)malloc(sizeof(int));]
3. new can be overloaded. malloc cannot be.
4. new does not need you to specify the size of the object being allocated.
[C * c = new C;]
Arrays are one-dimensional data structures that are stored contiguously in
memory. They support very fast random access since the memory address of any given
element can be calculated by multiplying the index of the element by the size of an
element and adding the result to the base address of the array. But arrays are very
expensive if you have to insert elements into the array, since the entire array past the
element inserted has to be moved to make room for the element to be inserted. Arrays
can grow and shrink as necessary.
Lists are similar to arrays but are stored very differently. Each element in a list
also includes a pointer to the previous and next elements, making it a doubly linked list.
It is very fast to add or delete items because doing so only involves changing a few
pointers. However, searching a list can be expensive since all searches need to start at
one of the list's ends.
Maps relate a key value to a data value. For instance, the key of a map could be
a string and the data a pointer into a list. You would ask the map to give you the pointer
associated with a particular string. Map lookups are fast because maps use hash tables
for key lookups. Adding and deleting items is also fast. Maps are often used with other
data structures as auxiliary indices. MFC uses a special kind of map called a message
map to map Windows messages to a pointer to the handler function for that message.

Advantages of delete over malloc


1. delete can be overloaded. free cannot.
2. delete invokes the destructor of the object to be deallocated. free
does not do this.

But internally both new and delete make use of malloc and free.
new generates exception in case of a failure

Вам также может понравиться