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

const_cast

const_cast(expression) The const_cast<>() is used to add/remove const(ness) (or


volatile-ness) of a variable.
static_cast
static_cast(expression) The static_cast<>() is used to cast between the integer
types. 'e.g.' char->long, int->short etc.
Static cast is also used to cast pointers to related types, for example casting
void* to the appropriate type.
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time, generally f
or the purpose of casting a pointer
or reference up or down an inheritance chain (inheritance hierarchy).
dynamic_cast(expression)
The target type must be a pointer or reference type, and the expression must eva
luate to a pointer or reference.
Dynamic cast works only when the type of object to which the expression refers i
s compatible with the target type
and the base class has at least one virtual member function. If not, and the typ
e of expression being cast is a
pointer, NULL is returned, if a dynamic cast on a reference fails, a bad_cast ex
ception is thrown. When it doesn't
fail, dynamic cast returns a pointer or reference of the target type to the obje
ct to which expression referred.
reinterpret_cast
Reinterpret cast simply casts one type bitwise to another. Any pointer or integr
al type can be casted to any other
with reinterpret cast, easily allowing for misuse. For instance, with reinterpre
t cast one might, unsafely,
cast an integer pointer to a string pointer
static_cast
static_cast is used for cases where you basically want to reverse an implicit co
nversion, with a few restrictions
and additions. static_cast performs no runtime checks. This should be used if yo
u know that you refer to an object
of a specific type, and thus a check would be unnecessary. Example:
void func(void *data) {
// conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main()
{
MyClass c;
start_thread(&func, &c).join();
}
In this example, you know that you passed a MyClass object, and thus there is no
need for a runtime check to ensure
this.
dynamic_cast
dynamic_cast is used for cases where you don't know what the dynamic type of the
object is. You cannot use
dynamic_cast if you downcast and the argument type is not polymorphic. An exampl
e
if(JumpStm *j = dynamic_cast<JumpStm*>(&stm))
{
...
} else if(ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}
dynamic_cast returns a null pointer if the object referred to doesn't contain th
e type casted to as a base class
(when you cast to a reference, a bad_cast exception is thrown in that case).
The following code is not valid, because Base is not polymorphic (doesn't contai
n a virtual function):
struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // invalid
}
An "up-cast" is always valid with both static_cast and dynamic_cast, and also wi
thout any cast,
as an "up-cast" is an implicit conversion

what is pipes and how it works


Simply put, a pipe is a set of two file descriptors that behave like an actual p
ipe.
You pump data into one end of the pipe, it comes out the other. The two file des
criptors being the two end of the
pipe.In many applications there is a need for various processes to communicate w
ith each other - exchanging data
or control information. This can be done by various methods like Pipes, signals,
shared memory, message queues etc.
Pipes can be used for such inter process communications - When you want one proc
ess to send data to another process,
you just write into one end of the pipe and the process on the other end can re
ad it out of the pipe.
A pipe is created by the system call pipe(). It gives you two file descriptors -
first for reading from the pipe
and the other for writing into the pipe.
In typical applications, it is used as follows:
The parent process creates a pipe and gets two file descriptor for the pipe - on
e to read and other to write.
Now the process forks another process. Now both child and parent has the copy of
these file descriptors.
Now, say, we want the child process to send some data to the parent process. The
n, the child process will write
this data into the write file descriptor using write(). The parent can then read
out this data from the read file
descriptor using read().
In fact, the Unix command line pipeline '|' also uses the same pipe. eg: if you
issue the command `ls | grep foo`
Then two processes are created - one for `ls` one for `grep` and a pipe is creat
ed to communicate between them.
The ls output is written into the write end of the pipe, and the output is read
into grep process from the read end
of the pipe.
The pipe() system call creates an anonymous pipe. i.e. such pipes do not have an
y names/identifier which can be
associated with them, they are identified by their file descriptor pair only, so
they can only be used when you
fork the processes form a parent who created the pipe and can hence pass on the
file descriptors. Such anonymous
pipes cannot be used between two entirely different processes as there is no way
to pass on the file descriptors.
To solve this problem too, Unix has a solution - there is something called named
pipe, also known as FIFO.
such pipes have a file name and are saved in the disk (can be seen in the ls out
put as a special size-zero file).
And this filename can be used by different processes to open and access the nam
ed pipe