0% found this document useful (0 votes)
54 views13 pages

C and C++questions

The document discusses virtual functions and polymorphism in C++ and C. Virtual functions allow dynamic binding at runtime through the use of virtual tables. The document also provides examples of implementing polymorphism and virtual functions in both C++ and C to illustrate the differences.

Uploaded by

roost69
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
54 views13 pages

C and C++questions

The document discusses virtual functions and polymorphism in C++ and C. Virtual functions allow dynamic binding at runtime through the use of virtual tables. The document also provides examples of implementing polymorphism and virtual functions in both C++ and C to illustrate the differences.

Uploaded by

roost69
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 13

1.

What is the output of printf("%d") – prints zero


When we use %d the compiler internally uses it to access the argument in the stack (argument stack).
Ideally compiler determines the offset of the data variable depending on the format specification string.
Now when we write printf(“%d”, a) then compiler first accesses the top most element in the argument
stack of the printf which is %d and dependent on the format string it calculated to offset to the actual
data variable in the memory which is to be printed. Now when only %d will be present in the printf
then compiler will calculate the correct offset (which will be the offset to access the integer variable)
but as the actual data object is to be printed is not present at that memory location so it will print
whatever will be the contents of that memory location.

2. What will happen if I say delete this?


The destructor will be executed, but memory will not be freed (other than the work done by destructor).
For example, if we have a class Test and inside we have a method Destroy that calls delete this, the
destructor for Test will execute.

If we have Test *var=new Test(), the pointer var will still be valid.

3. Difference between "C structure" and "C++ structure".


C structure does not support member functions to be declared in the structure whereas C++ structure
can have member functions declared in them.

4. Difference between "assignment operator" and "copy constructor".


In assignment operator you’re equating an existing object to an already existing object but in copy
constructor you’re creating a new object and then equating the already existing one to the new one.
example:
complex c1,c2;
c1=c2;//this is assignment
complex c3=c2;//copy constructor

5. What is the difference between "overloading" and "overriding"?


Overloading - Two functions having same name and return type, but with different type and/or number
of arguments.
Overriding - When a function of base class is re-defined in the derived class.

6. Explain the need for "Virtual Destructor".


Destructors are declared as virtual because if it is not declared as virtual the base class destructor will
be called before the derived class destructor and that will lead to memory leak because derived class’s
objects will not get freed. Destructors are declared virtual so as to bind objects to the methods at
runtime so that appropriate destructor is called.

7. Can we have "Virtual Constructors"?


YES. Please follow http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8
An idiom that allows you to do something that C++ doesn't directly support.

You can get the effect of a virtual constructor by a virtual clone() member function (for copy
constructing), or a virtual create() member function (for the default constructor).

class Shape {
public:
virtual ~Shape() { } // A virtual destructor
virtual void draw() = 0; // A pure virtual function
virtual void move() = 0;
...
virtual Shape* clone() const = 0; // Uses the copy constructor
virtual Shape* create() const = 0; // Uses the default constructor
};

class Circle : public Shape {


public:
Circle* clone() const; // Covariant Return Types; see below
Circle* create() const; // Covariant Return Types; see below
...
};

Circle* Circle::clone() const { return new Circle(*this); }


Circle* Circle::create() const { return new Circle(); }
In the clone() member function, the new Circle(*this) code calls Circle's copy constructor to copy the
state of this into the newly created Circle object. (Note: unless Circle is known to be final (AKA a
leaf), you can reduce the chance of slicing by making its copy constructor protected.) In the create()
member function, the new Circle() code calls Circle's default constructor.

Users use these as if they were "virtual constructors":

void userCode(Shape& s)
{
Shape* s2 = s.clone();
Shape* s3 = s.create();
...
delete s2; // You need a virtual destructor here
delete s3;
}
This function will work correctly regardless of whether the Shape is a Circle, Square, or some other
kind-of Shape that doesn't even exist yet.
Note: The return type of Circle's clone() member function is intentionally different from the return type
of Shape's clone() member function. This is called Covariant Return Types, a feature that was not
originally part of the language. If your compiler complains at the declaration of Circle* clone() const
within class Circle (e.g., saying "The return type is different" or "The member function's type differs
from the base class virtual function by return type alone"), you have an old compiler and you'll have to
change the return type to Shape*.

8. What are the different types of polymorphism?


Ad hoc polymorphism (overloading)

Parameterized polymorphism (Templates)

Pure Polymorphism (Overriding)

9. What are Virtual Functions? How to implement virtual functions?


There's some confusion around here - virtual functions have not been implemented in C++, but they
are part of the C++ language - that's something different. A C++ compiler needs to know how to build a
virtual table, but that's completely independent from the language in which the compiler is written.
What do you mean by "implementing virtual tables in C"? Do you want to write a C++ compiler in C?
Or a preprocessor which extends the C language to have classes, something like Objective-C? (virtual
functions don't make sense without the concept of classes and inheritance).

Anyway, a few words about how virtual functions are commonly implemented: When the C++
compiler finds a class with at least one virtual function, it will create a virtual table (vtable) for that
class. The vtable exists once per class and is basically an array of function pointers. The table is
initialized with the addresses of the actual virtual member functions that class implements. Each
instance of that class carries a pointer to the vtable of its class (the virtual pointer, or vptr) at a fixed
location, usually at the beginning of the memory occupied by the instance. Now when a function call is
encountered, the compiler would normally generate a call to the address of that function. But for virtual
functions calls, the compiler generates code which uses the vprt to look up the function pointer at a
certain index in the vtable, and calls the function through that pointer.

As an example, let's say class A has a virtual function foo(): let's assume that the address of that
function will be placed as the second entry in the vtable of class A. Now a class B is derived from A,
and foo() gets a new implementation in B: The address of B:foo() will be placed at the same index (2)
of B's vtable. Now at runtime we have an A pointer (pA) which points to an instance of B. When we
call foo() through that pointer, the generated code takes the address it finds at the beginning of the
memory pointed to by pA. Since the instance is actually of type B, it will find the address of B's vtable
in the vptr. It will then call the function it finds as the second entry in that table, which is B's
implementation of foo().
C++ virtual function is

• A member function of a class


• Declared with virtual keyword
• Usually has a different functionality in the derived class
• A function call is resolved at run-time

C language equivalent exists to a C++ program, then yes you can most certainly do polymorphism in
C. You will have some extra work to get it done.
struct MyClass // remember, in C++ a struct is a class that defaults to public.
{
long _iID;
char _strLabel[16];
MyClass(long iID) : _iID(iID)
{
memset(_strLabel, 0, sizeof _strLabel);
}
virtual bool doSomething();
};

bool MyClass::doSomething()
{
printf("ID = %ld Label = %-*.*s\n", _iID, sizeof(_strLabel), sizeof(_strLabel), _strLabel);
}

/*
C example with data member that is a function pointer used to simulate a virtual method.
Notice how much more verbose the C example is compared to the C++ example above.
*/

#include <stdio.h>

struct MyClass
{
long _iID;
char _strLabel[16];

/* sorry, no constructor here but see below!! */


bool (*_pDoSomething)(struct MyClass *pThis);
};

extern struct MyClass *newInstance();

/*
code for C version of a virtual method. C doesn't have a "this"
pointer so
we have to explicitly create one here.
*/
static bool doSomething(struct MyClass *pThis)
{
printf("ID = %ld Label = %-*.*s\n",
pThis->_iID, sizeof(pThis->_strLabel), sizeof(pThis->_strLabel),
pThis->_strLabel);
}

// C equivalent to a constructor
struct MyClass *newInstance(long iID)
{
struct MyClass *pClass = (struct MyClass *)malloc(sizeof (MyClass) );
if (pClass)
{
pClass->_iID = iID;
memset(pClass->_strLabel, 0, sizeof pClass->_strLabel);
// assign virtual method.
pClass->_pDoSomething = doSomething;
}
return pClass;
}

/* typical usage for C class above ... */


int main(int argc, char *argv[])
{
/* constructor called to create / initialize instance. */
MyClass *pClass = newInstance(100);
if (pClass)
{
strcnpy(pClass->_strLabel, "Howdy folks.", sizeof(pClass->_strLabel));
pClass->_pDoSomething();
/* ... and here's a non-virtual method call. */
doSomething(pClass);
/* (non-virtual) destructor call. */
free(pClass);
}
return 0;
}

10. What are the different types of storage classes?


Storage classes include: auto, extern, register, static.

The auto keyword places the specified variable into the stack area of memory. This is usually
implicit in most variable declarations, e.g. int i;

The extern keyword makes the specified variable access the variable of the same name from some
other file. This is very useful for sharing variables in modular programs.
The register keyword suggests to the compiler to place the particular variable in the fast register
memory located directly on the CPU. Most compilers these days (like gcc) are so smart that
suggesting registers could actually make your program slower.

The static keyword is useful for extending the lifetime of a particular variable. If you declare a static
variable inside a function, the variable remains even after the function call is long gone (the variable is
placed in the alterable area of memory). The static keyword is overloaded. It is also used to declare
variables to be private to a certain file only when declared with global variables. Static can also be used
with functions, making those functions visible only to the file itself.

11. What is Namespace? Namespaces allow to group entities like classes, objects and functions under a
name. This way the global scope can be divided in "sub-scopes", each one with its own name. The
format of namespaces is:
namespace identifier{
entities
}

12. What are the types of STL containers?


Sequence Containers – deque, list, vector
Associative Containers - map(multimap), set(multiset)
Container Adapters - priority_queue, queue, stack

13. Difference between "vector" and "array".


Vector is also an array but the size of a vector can change dynamically where in array it’s fixed. We can
create some reserve space in vector where in array we cannot.

The size of array is fixed in compile time, so the size of array cannot be adjusted at run time to
accommodate changeling program. But vector can solve this problem by allocating memory as needed.

14. How to write a program such that it will delete itself after execution?
#include <cstdlib>
#include <cstdio>

int main(int argc, char **argv)


{
remove(argv[0]);
return EXIT_SUCCESS;
}

Provided that the program was launched from a file.

And on a platform/implementation that fills argv[0] with useful information. And on a


platform/implementation that allows you to delete executables. And on a platform/implementation that
doesn't lock executables while they're running. And on a platform/implementation that doesn't support
symbolic links, or passes the link's target, rather than the link itself, in usable format, to argv[0]. And
on a platform/implementation for which you have delete/write/whatever permissions to the file.
And........

15. Can we generate a C++ source code from the binary file?
There may be some software that attempts to generate c++ source code from the binary file, but it can
not reproduce the original source code. First, it doesn't know the names of the variables, it doesn't know
how everything was structured, or the names of the functions used. All of these are lost when the code
is compiled. it also can not know what code was optimized.
As far as large programs are concerned (such as a 3D racing game), there's no way you can reproduce
the C++ source code from their binary files. For simple programs, however, you should be able to do
that. Here's how and why.
A binary file is a file that results when you build a C++ program using your compiler and linker. In
order to create a binary, the compiler and the linker go through certain specific steps.
If you know these steps, then, logically, in order to convert the binary back to the C++ code you simply
have to trace these steps backwards.
In the case of large programs, however, that's easier said than done. For complex applications, these
steps of conversion are very very complicated. They are, therefore, almost impossible to understand
and trace backwards.
In the case of a simple program, on the other hand, the path from C++ code to the binary is pretty
straightforward. Consequently, it is relatively far easier to go back from a binary file and arrive at C++
code.
Sure enough, software applications are available that can do the above for you. They are called
disassemblers and decompilers. A disassembler converts a binary to a assembly language code and a
decomplier, as the name suggest, does the opposite of what a compiler does and converts assembly
code into a C++ (or any other high level language) code.

16. What are inline functions?


The inline function takes the format as a normal function but when it is compiled it is compiled as
inline code. The function is placed separately as inline function, thus adding readability to the source
program. When the program is compiled, the code present in function body is replaced in the place of
function call.

17. Talk some timing about profiling?


In software engineering, program profiling, software profiling or simply profiling, a form of
dynamic program analysis (as opposed to static code analysis), is the investigation of a program's
behavior using information gathered as the program executes. The usual purpose of this analysis is to
determine which sections of a program to optimize - to increase its overall speed, decrease its memory
requirement or sometimes both.
• A (code) profiler is a performance analysis tool that, most commonly, measures only the
frequency and duration of function calls, but there are other specific types of profilers (e.g.
memory profilers) in addition to more comprehensive profilers, capable of gathering extensive
performance data.
• An instruction set simulator which is also — by necessity — a profiler, can measure the
totality of a program's behaviour from invocation to termination.

18. How many lines of code you have written for a single program? thousands of lines

19. What is “strstream”?


strstream is the class that specializes iostream to use a strstreambuf for input and output with arrays of
characters in memory. You can create an strstream object by associating the object with a previously
allocated array of characters. You can then write output to it, read input from it, and apply other
operations to it just as you would to another type of stream.

20. How to write multithreaded applications using C++?


C++ doesn’t have the inbuilt thread functions. It can support through operating system calls.
http://www.devarticles.com/c/a/Cplusplus/Multithreading-in-C/

21. Explain "passing by value", "passing by pointer" and "passing by reference"


Passing by value means that a copy of the object is made on the callee’s stack and altering the object
means altering a local copy so the caller's object is unchanged when the function returns. Passing by
reference means that the address of the object is send (a reference holds an address but behaves like an
object) so that the callee can directly alter the original object.
Passing by pointer is a misconception. A pointer is a memory address. You can pass a pointer to a
function, but the pointer is passed by value. You can distinguish between the two this way: if the
parameter has a trailing & then it is passed by reference, otherwise by value.

Follow http://www.codeguru.com/forum/showthread.php?t=343473 for examples.


22. Write any small program that will compile in "C" but not in "C++"
http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B
%2B#Constructs_valid_in_C_but_not_C.2B.2B

The simplest way is to use C++ keywords as variable name, like class, mutable, new, delete and etc.

More advanced forms:


int main() {
void * v = 0;
char * p = v;
}

int main()
{
char* p = malloc(10);
return 0;
}
because of the implicit void* to char* conversion that a C++ compiler won't swallow

23. Have you heard of "mutable" keyword?


A mutable keyword is useful when we want to force a logical const data member to have its value
modified. A logical const can happen when we declare a data member as non-const, but we have a
const member function attempting to modify that data member.

class Dummy
{
public:
bool isValid() const;
private:
mutable int size_ = 0;
mutable bool validStatus_ = FALSE; // logical const issue resolved
};

bool Dummy::isValid() const // data members become bitwise const


{
if (size > 10)
{
validStatus_ = TRUE; // fine to assign
size = 0; // fine to assign
}
}

24. What is a "RTTI"?


It is run time type identification. In an inheritance hierarchy we can find out the exact type of the object
of which it is member.
It can be done by using:
1) dynamic id operator
2) typecast operator.

26. Why pre increment operator is faster than post increment?


Post increment needs preserving value.

27. What is the difference between "calloc" and "malloc"?


calloc: allocate array of objects
malloc: allocate single object
In calloc default value will be ZERO when the memory is allocated
whereas in malloc default value will be GARBAGE values

28. What will happen if I allocate memory using "new" and free it using "free" or allocate it using
"calloc" and free it using "delete"?
Memory leak??

29. What is Memory Alignment?


Memory alignment is the restriction imposed on memory allocation in such a way that values
associated with multibyte get assigned only at certain places of memory. Such Memory alignment
though generally not very common issue in OOPS terminology as the compiler takes care of allocation
of bytes at proper locations.

30. Explain working of printf.


printf is defined as: char *printf(const char *control-string, ...);
char *control-string defines the control string. the ellipse (...) defines printf has having any number of
any type of parameters after the control string.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

char *newfmt(const char *fmt, ...){


char *p;
va_list ap;
if ((p = malloc(128)) == NULL)
return (NULL);
va_start(ap, fmt);
(void) vsnprintf(p, 128, fmt, ap);
va_end(ap);
return (p);
}

/* Plus a little routine to show how it is used. */


int main(int ac, char *av) {
int a = 42;
char *str;
str = newfmt("%d", a);
if (!str) {
fprintf(STDERR, "Out of memory!\n");
exit(5);
}
printf("%s\n", str);
free(str);
return 0;
}
31. Difference between "printf" and "sprintf".
sprintf writes data to the charecter array whereas printf writes data to the standard output device

32. What is "map" in STL? An associative container

33. When shall I use Multiple Inheritance? When to inherit features from more than one class.

34. What are the techniques you use for debugging?


Now that we have learned the basics of Makefiles, we can now look into debugging our code in
conjunction with Makefiles. As an introduction we will be using three debugging techniques:

1. Non-interactive
2. GNU gdb
3. dbx

Follow the link http://vergil.chemistry.gatech.edu/resources/programming/c-tutorial/debug.html

35. How to reduce the final size of executable?


http://www.catch22.net/tuts/minexe
Size of the final executable can be reduced using dynamic linking for libraries.

36. Give two examples of code optimization.


http://www.eventhelix.com/realtimemantra/basics/optimizingcandcppcode.htm
Use constructor initialization lists

Break big switch statements into nested switches

Follow http://www.eventhelix.com/RealtimeMantra/Basics/OptimizingCAndCPPCode.htm

You might also like