C,C++,VC++ Interview Questions
C,C++,VC++ Interview Questions
How you will reverse the string with out using any function
see, both are same in the sense different data types can be used as a unit.
for this structure the memory will be allocated as (int-2 bytes,float-4 bytes,char-2 bytes)
union problem
{
int a;
char b[2];
float f;
}x;
here memory will be allocated only for the largest variable. i.e float in this case .the size
of the above union is 4 bytes .thats it. and other point is here in union if we change one
value automatically other values will be changed vector and list
The zero fill is all-bits-zero, and does not therefore guarantee useful null pointer
values (see section 5 of this list) or floating-point zero values. free is properly used to
free the memory allocated by calloc.
malloc(s);
returns a pointer for enough storage for an object of s bytes.
calloc(n,s);
returns a pointer for enough contiguous storage for n objects, each of s bytes. The
storage is all initialised to zeros.
malloc takes a single argument and allocates bytes of memory as per the argument
taken during its invocation. Where as calloc takes two augments, they are the number
of variables to be created and the capacity of each variable i.e. the bytes per variable
OOPS Concepts
1.Structure: Initially (in C) a structure was used to bundle different type of data types
together to perform a particular functionality. But C++ extended the structure to contain
functions also. The major difference is that all declarations inside a structure are by
default public
Class: Class is a successor of Structure. By default all the members inside the class are
private.
2) structures in c++ doesn't provide data hiding where as a class provides data hiding
classes support polymorphism, whereas structures don't
3) class and structure are very similar. The former is heavyweight while the latter is light
weight. Reference to the former rests on the heap. While the latter in whole (instance and
data) rests on the stack. Therefore care should be taken not to make a struct very heavy
else it overloads the stack causing memory hogging. Class needs to have an instance
explicitly created to be used. A struct doesn't have to be explicitly initiated
The scheme for producing a mangled name differs with the object model used to
compile the source code: the mangled name of an object of a class compiled using
one object model will be different from that of an object of the same class compiled
using a different object model. The object model is controlled by compiler option or
by pragma.
Name mangling is not desirable when linking C modules with libraries or object files
compiled with a C++ compiler. To prevent the C++ compiler from mangling the
name of a function, you can apply the extern "C" linkage specifier to the declaration
or declarations, as shown in the following example:
extern "C" {
int f1(int);
int f2(int);
int f3(int);
};
This declaration tells the compiler that references to the functions f1, f2, and f3
should not be mangled. The extern "C" linkage specifier can also be used to
prevent mangling of functions that are defined in C++ so that they can be called from
C. For example,
extern "C" {
void p(int){
/* not mangled */
}
};
If your class has at least one virtual function, you should make a destructor for this class
virtual. This will allow you to delete a dynamic object through a caller to a base
class object. If the destructor is non-virtual, then wrong destructor will be invoked during
deletion of the dynamic object. When We Declare a Virtual Function In Base Class.
The Base Class Pointer Can Point To Derived Class objects. And If we Try To Delete
The Base Class Pointer ,it will Call the base Class Destructor(Which Is Wrong).
Static variables:
Static block will be executed automatically when jvm(Java Virtual Machine)loading the
class into memory.
static variable can be called using both object name & class name.
memory will be allocated when JVM loads the class.
static variable retains its value like a global variable, but visible with in the scope.
While non static variable will not be retained one it come out of the scope or block.
Again the visibility is local to the block.
b) Initialization IS about creating object assignment IS about setting some value to object.
This is why in the following code:
AXC d = 3;
AXC x;
x = 2;
first line will require an appropriate constructor:
AXC(int i) { ... }
whereas the third line will use overloaded assignment "=" operator if its specified (if not,
it will use constructor like above):
AXC operator =(int x) { ... }
Explanation 1:
Virtual concept achieves dynamic binding. Not the Points below:
1. When the class uses virtual functions a V-Table is created for this class, to resolve
members of the class. V-Table has pointers of base addresses to the class members.
2. There are no virtual constructor, because when the object is in construction, there is
no V-Table created. so no binding possible.
3. Virtual destructors are best practice of programming. This is must because when the
base class is destroyed using delete operator then the derived object can't deleted,
then it possess memory leaks. when u use virtual destructor the derived class
destructor called by delete operator.
4. When ever we are creating an object for a class using new operator, then at that point
of time we should know what type of object we are creating, the new operator will
invoke the constructor so if we don't know the type of the constructor then it is not
possible to create that so because of this response virtual constructor in not possible.
Explanation 2:
Technical reason
The object exists only after the constructor ends.In order for the constructor to be
dispatched using the virtual table , there has to be an existing object with a pointer to the
virtual table , but how can a pointer to the virtual table exist if the object still doesn't
exist? :)
Logic reason
You use the virtual keyword when you want to declare a somewhat polymorphic
behavior. But there is nothing polymorphic with constructors , constructors job in C++ is
to simply put an object data on the memory . Since virtual tables (and polymorphism in
general) are all about polymorphic behavior rather on polymorphic data , There is no
sense with declaring a virtual constructor.
Explanation 3:
Constructor is called at the time of object creation & there u always know what is the
class type? ... Constructors are local to class. In case of destructor we need to call
destructor on the basis of type of object hence it should be virtual. you need a virtual
destructor every time u use a base class pointer to access derived class object
(dynamically) & then use it to call derived class destructor.
class derived
{
derived(){cout << n this is derived constructor ;
~derived(){cout << n this is derived destructor ;
};
int main()
{
base *p new derived;
delete p;
}
Look at the order carefully base class constructor is called first & its destructor is called
at last... Now consider if compiler allows us to make constructor virtual then in that case
when we call base *p new derived ; No constructor of base class would be called; which
is an error in itself...
However in case of destructors (as they are called in reverse order of creation) if we don't
have declared it as virtual only base class destructor would have been called... which we
don't want here....
Moreover the constructors & destructors can't be pure virtual as it would make the
derived class as abstract base classes (as they can't overwrite constructor/destructor of
base class)....
Explanation 4:
A constructor cannot be virtual because at the time when the constructor is invoked the
virtual table (vtable) 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.
Virtual methods should be used judiciously as they are slow due to the overhead involved
in searching the virtual table. They also increase the size of an object of a class by the
size of a pointer.
Explanation 5:
Constructors are called at object creation time and complete information about the object
is known so the compiler knows exactly which constructors to call. Also in a derived
object constructors in the base classes are called before the constructor in the most
derived object. As such constructor cannot be virtual because having a virtual constructor
would mean the order of construction can be altered which will break object
initialization.
Thread Process
Threads share the address space of the Processes have their own address
process that created it
Threads have direct access to the data Processes have their own copy of the data
segment of its process segment of the parent process.
Threads can directly communicate with Processes must use inter process
other threads of its process communication to communicate with
sibling processes.
Threads have almost no overhead processes have considerable overhead.
New threads are easily created new processes require duplication of the
parent process.
Threads can exercise considerable control Processes can only exercise control over
over threads of the same process child processes.
Changes to the main thread (cancellation, Changes to the parent process does not
priority change, etc.) may affect the affect child processes.
behavior of the other threads of the process
thread is a light weight process(flow of Process is heavy weight (heavy weight)
execution throw the process code).... process
Explanation 2:
process is a execution of a program and program contain set of instructions but thread is a
single sequence stream within the process.thread is sometime called lightweight process.
single thread allows a OS to perform single task data time similarities between process
and threads are:
Similarities
1) Share CPU.
2) Sequential execution
3) Create child
4) If one thread is blocked then the next will be start to run like process.
Dissimilarities:
1) Threads are not independent like process.
2) All threads can access every address in the task unlike process.
3) Threads are design to assist on another and process might or not might be assisted on
one another.
Answer
By default, C++ matches a function call with the correct function definition at compile
time. This is called static binding. You can specify that the compiler match a function call
with the correct function definition at run time; this is called dynamic binding. You
declare a function with the keyword virtual if you want the compiler to use dynamic
binding for that specific function.
The following examples demonstrate the differences between static and dynamic binding.
The first example demonstrates static binding:
#include <iostream>
using namespace std;
struct A {
void f() { cout << "Class A" << endl; }
};
struct B: A {
void f() { cout << "Class B" << endl; }
};
int main() {
B x;
g(x);
}
Class A
When function g() is called, function A::f() is called, although the argument refers to
an object of type B. At compile time, the compiler knows only that the argument of
function g() will be a reference to an object derived from A; it cannot determine whether
the argument will be a reference to an object of type A or type B. However, this can be
determined at run time. The following example is the same as the previous example,
except that A::f() is declared with the virtual keyword:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f() { cout << "Class B" << endl; }
};
int main() {
B x;
g(x);
}
Class B
The virtual keyword indicates to the compiler that it should choose the appropriate
definition of f() not by the type of reference, but by the type of object that the reference
refers to.
Therefore, a virtual function is a member function you may redefine for other derived
classes, and can ensure that the compiler will call the redefined virtual function for an
object of the corresponding derived class, even if you call that function with a pointer or
reference to a base class of the object.
You redefine a virtual member function, like any member function, in any derived class.
Suppose you declare a virtual function named f in a class A, and you derive directly or
indirectly from A a class named B. If you declare a function named f in class B with the
same name and same parameter list as A::f, then B::f is also virtual (regardless whether
or not you declare B::f with the virtual keyword) and it overrides A::f. However, if
the parameter lists of A::f and B::f are different, A::f and B::f are considered
different, B::f does not override A::f, and B::f is not virtual (unless you have declared
it with the virtual keyword). Instead B::f hides A::f. The following example
demonstrates this:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
Class A
Class C
The function B::f is not virtual. It hides A::f. Thus the compiler will not allow the
function call b.f(). The function C::f is virtual; it overrides A::f even though A::f is
not visible in C.
If you declare a base class destructor as virtual, a derived class destructor will override
that base class destructor, even though destructors are not inherited.
The return type of an overriding virtual function may differ from the return type of the
overridden virtual function. This overriding function would then be called a covariant
virtual function. Suppose that B::f overrides the virtual function A::f. The return types
of A::f and B::f may differ if all the following conditions are met:
• The function B::f returns a reference or pointer to a class of type T, and A::f
returns a pointer or a reference to an unambiguous direct or indirect base class of
T.
• The const or volatile qualification of the pointer or reference returned by B::f has
the same or less const or volatile qualification of the pointer or reference returned
by A::f.
• The return type of B::f must be complete at the point of declaration of B::f, or it
can be of type B.
#include <iostream>
using namespace std;
struct A { };
class B : private A {
friend class D;
friend class F;
};
A global_A;
B global_B;
struct C {
virtual A* f() {
cout << "A* C::f()" << endl;
return &global_A;
}
};
struct D : C {
B* f() {
cout << "B* D::f()" << endl;
return &global_B;
}
};
struct E;
struct F : C {
// Error:
// E is incomplete
// E* f();
};
struct G : C {
// Error:
// A is an inaccessible base class of B
// B* f();
};
int main() {
D d;
C* cp = &d;
D* dp = &d;
A* ap = cp->f();
B* bp = dp->f();
};
The following is the output of the above example:
B* D::f()
B* D::f()
The statement A* ap = cp->f() calls D::f() and converts the pointer returned to type
A*. The statement B* bp = dp->f() calls D::f() as well but does not convert the
pointer returned; the type returned is B*. The compiler would not allow the declaration of
the virtual function F::f() because E is not a complete class. The compiler would not
allow the declaration of the virtual function G::f() because class A is not an accessible
base class of B (unlike friend classes D and F, the definition of B does not give access to
its members for class G).
If a function is declared virtual in its base class, you can still access it directly using the
scope resolution (::) operator. In this case, the virtual function call mechanism is
suppressed and the function implementation defined in the base class is used. In addition,
if you do not override a virtual member function in a derived class, a call to that function
uses the function implementation defined in the base class.
• Defined
• Declared pure
• Defined and declared pure
A base class containing one or more pure virtual member functions is called an abstract
class.
Function Overloading
Answer
In order to overload a function, a different signature should be used for each overloaded
version. A function signature consists of the list of types of its arguments as well as their
order. Here's a set of valid overloaded versions of a function named f:
void f(char c, int i);
void f(int i, char c);
void f(string & s);
void f();
void f(int i);
void f(char c);
Note, however, that a function differing only by return type is illegal (it is legal to use
different a return type with a different argument list, though) :
int f(); //error; differs from void f(); above only by return type
int f(float f); //fine. unique signature
/////////////////////////////////////////////////////////////////
It is necessary(No idea about java but in C++ it's so). Because the call to a function is
bound to the function definition only by its signature i.e. its name, no of parameters, type
of parameters(and other factors like virtual function come into picture for dynamic
binding but not the return value for sure). Another reason might be the fact that the
return value of a function can be ignored in the program.
Consider the following scenario.
Another way of looking at the issue is: Why will a machine return different type of output
for the same types of input?
Can we use resume in error handling i.e. in the catch block Answer
Answer
The question could be: Can we resume the execution from where the exception is
thrown?
What is an array
Answer
Memory alignment is the restriction imposed on memory allocation in such a way that
values associated with multi byte 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.
Variable scope is the places in code where this variable can be accessed
Variable can be defined to be global (visible in the program include scope)
Variable can be local if defined in the scope of parenthesis (inside function or in
compound statement)
In classes variables scope depends on the way it is defined (private, public or protected)
What is the difference between static link library and dynamic link library?
Answer
Static libraries are linked at compile time. Dynamic libraries are linked at runtime. Static
library is faster than dynamic library the executable exe size will be larger when we build
exe with static library compared to dynamic library In case of Dynamic Library your
executable will look up for the code at run time. E.g. when running some exe it looks for
help from some .dll files provided by windows operating system. So we call this
dynamic linking.
The static linked library causes the corresponding information from libraries to be
included in the executable DLL on the other hand inserts virtual address of memory.
Thus the size of static linked file is larger than a static linked file. If we use dynamic
linking the updates in library will also be effect the behavior of the file while not in static
linking. Due to this reason dll is better but it can also sometimes make the program faulty
due to library update.
What is the difference between vector and list
the C++ standard library as defined by ISO/ANSI does contain two classes 'std::vector'
and 'std::list', among others. 'vector' is an automatically resizable 'array', and 'list' is
well, a linked list. Which to use depends upon what you need to do with your data.
With a vector, you have random access to any element in constant time, as well as adding
elements to the end of the vector in constant time. However, insertions and deletions take
more time, proportionate to the number of subsequent or previous elements that need to
be 'pushed down' or 'moved back' to make room for the new element or to contract the
vector into the just 'emptied' slot.
With a list, you don't have random access (you must 'follow the links' to reach any
element), but insertions and deletions are done in constant time.
Vectors are normally implemented in ONE bulk linear, which makes it slow to
add items if you increase above the buffer of them. Lists are normally implemented using
linked lists, which makes an insertion fast, but a retrieval slow. If you know the size
(approximately) use vector and set the buffer to that size, if you don't know size use list...
Introduction
This article is about the slicing of object while sending the argument through a pass by
value mechanism when using polymorphism.
Background
While we are using passing by address mechanism the address of the base class type as
well as the derived class type are same in size. But the object of the derived class is
usually bigger than the base class. So while we upcast an object instead of reference or
pointer the object will be sliced. Let we have a function which takes an argument as base
class type object. Now if we call this function with a derived class object as parameter
then the compiler will copy only the base portion of the object the derived portion of the
object will be sliced.
Code:
Derived object before slice Derived object after slice
------------------------------- -------------------------------
Derived vptr Base vptr
Member variables of base class Member variables of base class
Member variables of derived class
Since the compiler knows that a particular type of object will be passed as value so the
derived object has been forced to become a base object. When passing by value the copy
constructor of the base object will be used and which will initialize the VPTR (Derived
object) with the base VTABLE and will copy only the base part of the object.
The code
Code:
#include <iostream>
#include <string>
using namespace std;
class Base
{
string BaseName;
public:
Base(const string& basename) : BaseName(basename) {}
string Name()
{
return BaseName;
}
public:
Derived(const string& basename, const string& derivedname)
: Base(basename), DerivedName(derivedname) {}
string Information()
{
return DerivedName + "Derive from " +
Base::Name();
}
};
int main() {
Base base("Animal");
Derived derived("Dog", "Animal");
CreateSliceObject(base);
CreateSliceObject(derived);
}
Now if we declare a function as pure virtual in the base class then the compiler will
prevent the object slicing because it will not allow creating an object of base type (This is
generally happen for upcast by value). The compiler will show a compilation error and
will prevent the object slicing.
Code:
class Base
{
string BaseName;
public:
Base(const string& basename) : BaseName(basename) {}
string Name()
{
return BaseName;
}
WIN32/ MFC
The PostMessage function places (posts) a message in the message queue associated with
the thread that created the specified window and then returns without waiting for the
thread to process the message.
The SendMessage function sends the specified message to a window or windows. The
function calls the window procedure for the specified window and does not return until
the window procedure has processed the message.
OnPaint():
It is message-handler function .
OnDraw() is ultimately called by OnPaint(), as you can find inside MFC sources:
void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
OnPaint() OnDraw()
OnPaint is called for windows, dialogs and OnDraw is called for Views, ,. There is
controls little, if any, functional difference.
OnPaint is a WM_PAINT message handler OnDraw is a virtual function.
OnPaint handler for views call a virtual
function OnDraw.
One other difference is that the doc/view OnDraw() is a higher level abstraction and
framework will use your OnDraw() code is part of the document/view architecture.
when printing, as well as displaying on the CView implements OnPaint() and
screen.Actually, that's the fundamental OnPrint() and routes them both to OnDraw.
difference between OnPaint() and In addition, it creates the necessary calls to
OnDraw(). So while OnPaint and OnPrint BeginPaint() / EndPaint() and adds a lot of
are just handlers for the WM_PAINT and code to handle print previewing. Only this
WM_PRINT messages, respectiveley (and allows you to use the same drawing code
can be implemented in any class derived for drawing to the screen, printing and print
from CWnd), previewing.
OnPaint is the member function of Cwnd, OnDraw is the
member function of CView
In contrast, MFC, which stands for Microsoft Foundation Classes, are a collection of C++
classes which encapsulate the Win32 API. MFC has some wizards which make the initial
creation of a program quick and easy, but I have to admit the learning curve of MFC can
sometimes be frustrating as Microsoft seems to have done everything in a way that can at
times seem counter-intuitive.
Whenever I write an application I write it in MFC but I have been writing applications in
MFC for a long time. If all you want is a message loop and a window handle for a game,
use Win32. If you want to write a larger application like an editor, maybe MFC is the
right tool.
MFC is basicly a library of OO wrapper classes that wrap the Win32 api, and provide
objects for the basic window components (windows, buttons, checkboxes etc..).
Essentially it is the win32 api objectified.
Also MFC provides some classes that resemble classes found in the STL. As MFC was
made before STL was fully standardised.
What’s the difference between PostMessage and SendMessage?
The PostMessage function places (posts) a message in the message queue associated with
the thread that created the specified window and then returns without waiting for the
thread to process the message.
The SendMessage function sends the specified message to a window or windows. The
function calls the window procedure for the specified window and does not return until
the window procedure has processed the message.
GetMessage function waits for a message to be placed in the queue before returning
where as PeekMessage function does not wait for a message to be placed in the queue
before returning.
m_pModeless->Create(IDD_DIALOG1, this);
m_pModeless->ShowWindow(SW_SHOW);
this pointer as a paramter suggest we are creating a child dialog of the current
dialog/window.
By default, MFC uses the resource handle of the main application to load the resource
template. If you have an exported function in a DLL, such as one that launches a dialog
box in the DLL, this template is actually stored in the DLL module. You need to switch
the module state for the correct handle to be used. You can do this by adding the
following code to the beginning of the function:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
This swaps the current module state with the state returned from
AfxGetStaticModuleState until the end of the current scope.
If all your resources lies in the single DLL you can even change the default handle to the
DLL handle with the help of AfxSetResourceHandle function.
The CArchive class allows you to save a complex network of objects in a permanent
binary form (usually disk storage) that persists after those objects are deleted. Later you
can load the objects from persistent storage, reconstituting them in memory. This process
of making data persistent is called “serialization.”
If I derive a new class from CObject what are the basic features my derived will
get?
It is the base class for the MFC library message map architecture. Which maps
commands/messages to the member functions to handle them. Classes derived from this
are CWnd, CWinApp, CFrameWnd, CView, CDocument
Can you explain the relationship between document, frame and view?
Next comes the message loop. In order to retrieve and dispatch messages, WinMain
executes a simple while loop that calls the GetMessage, TranslateMessage, and
DispatchMessage API functions repeatedly.
GetMessage checks the message queue. If a message is available, it is removed from the
queue and copied to msg;
TranslateMessage converts a keyboard message denoting a character key to an easier-to-
use WM_CHAR message,
and DispatchMessage dispatches the message to the window procedure. The message
loop executes until GetMessage returns 0, which happens only when a WM_QUIT
message is retrieved from the message queue. When this occurs, WinMain ends and the
program terminates.
When we create Modal Dialog Box we can't move to other windows until this dialog is
closed. For eg: MessageBox, where we can't move to the other window until we press ok
or cancel.
When we create Modeless Dilaog Box we can swap to the other windows. For eg: like a
conventional window.
In CommonDialogs class we have to use CFileDialog class where the first parameter
TRUE for open dialog and FALSE for Save dialog.
What is CSingleDocTemplate?
It’s a document template class used to create single document interface SDI applications.
Only one document can be opened at a time. It identifies the document class used to
manage the application's data, the frame window class that encloses views of that data,
and the view class used to draw visual representations of the data. The document template
also stores a resource ID that the framework uses to load menus, accelerators, and other
resources that shape the application's user interface.
What is the difference between hinstance and hprevinstance in WinMain function?
hInstance is used for things like loading resources and any other task which is performed
on a per-module basis. A module is either the EXE or a DLL loaded into your program.
hPrevInstance used to be the handle to the previously run instance of your program (if
any) in Win16. It is always NULL for Win32 programs.
This message is sent to the dialog box during the Create, CreateIndirect, or DoModal
calls, which occur immediately before the dialog box is displayed. This can be used to
intialize the dialog controls or show/hide the controls etc.,
This is to initialize data in a dialog box, or to retrieve and validate dialog data.
The framework automatically calls UpdateData with bSaveAndValidate set to FALSE
when a modal dialog box is created in the default implementation of
CDialog::OnInitDialog. The call occurs before the dialog box is visible. The default
implementation of CDialog::OnOK calls this member function with bSaveAndValidate
set to TRUE to retrieve the data, and if successful, will close the dialog box. If the Cancel
button is clicked in the dialog box, the dialog box is closed without the data being
retrieved.
call UpdateAllViews()- which updates all views associated with the document by calling
OnUpdate() function of all the views.
1.Dynamic_cast operator
Used for conversion of polymorphic types.
2.typeid - used for identifying the exact type of an object
3. type_info class
used to hold the type information returned by typeid.
Searialization is the process of streaming the object data to or from a persistent storage
medium. It's useful in Doc-View Architecture. CObject :: Serialize() function is used to
do serialization.
2 types of thread in MFC are User Interface thread and worker thread. User Interface
threads maintain the message loops and used to handles user input, creates windows and
process messages sent to those windows. Worker thread don't use message loops and
mainly used to perform background operations such as printing etc., Created using
AfxBeginThread by passing Thread Function to create worker thread and Runtime class
object to create a user interface thread.
Mutex as the name suggest allows a mutullay exclusive access to a shared resource
among the threads. Critical section is a piece of code that can be executed safely to be
accessed by two or more threads. Criticalsection provides synchronization means for one
process only, while mutexes allow data synchronization across processes. Means two or
more threads can share the common resources among more than one application or process
boundaries in mutex.
What is socket?
MFC is a wrapper around win32 API, It provides classes which uses the win32 API,
Some of the API's we usually work with are :
GetDlgItemInt, GetDlgItemText, GetWindowTextA, MessageBoxA, CreateFile,
CreateMutex, CreateEvent, WaitForSingleObject, CreateWindow, ShowWindow etc.,
ANSI code represents 8bytes data where UNICODE represents 16bytes data for
supporting universal languages. One major draw back to ASCII was you could only have
256 different characters. However, languages such as Japanese and Arabic have
thousands of characters. Thus ASCII would not work in these situations. The result was
Unicode which allowed for up to 65,536 different characters
Regular dlls wraps only the c/c++ functions. Where extention dlls include c++ interfaces
where we can create the objects of it and use in our classes. Extended dlls support object
oriented concepts. Regural dlls uses mfc internally and exported functions can be used by
any mfc or non-mfc applications. Extention dlls implements reusable classes derived
from mfc library,built using dll version of mfc. Only mfc executables(applications/dll-
shared version of mfc) can use extention dlls. extention dlls used for passing mfc derived
objects b/w applications and dlls. Regular dlls linked both statically and dynamically but
extended dlls links dynamically.
What is a message map, and what is the advantage of a message map over virtual
function?
MessageMap is a logical table that maps the windows messages to the member functions
of the class. We use message maps over virtual function because of lots of overhead. If
every windows message had a virtual function associated with it , there would be several
hundred bytes per window class of v-table. Message maps means we only pay for the
messages we use.
private:
MyClass();
};
What is a message map, and what is the advantage of a message map over virtual
function?
Message Maps, maps the user action in to the appropriate MFC class functions to handle
it. The MFC Class which can handle message should be member of CCmdTarget, (i.e) it
should be hierarchically derived from CCmdTarget.
The BEGIN_MESSAGE_MAP macro at the start of the message map specifies two class
names as its arguments:
BEGIN_MESSAGE_MAP(CMyView, CView)
The first argument names the class to which the message map belongs. The second
argument provides a connection with the immediate base class — CView here — so the
framework can search its message map, too.
The message handlers provided in a base class are thus inherited by the derived class.
This is very similar to normal virtual member functions without needing to make all
handler member functions virtual which is an advantage since overhead of creating
VTable is eliminated.
If no handler is found in any of the base-class message maps, default processing of the
message is performed. If the message is a command, the framework routes it to the next
command target. If it is a standard Windows message, the message is passed to the
appropriate default window procedure.
Processes and thread are very similar but they differ in the way they share their resources.
Processes are independent and have its own address space. If two independent processes
want to communicate they do this by using the following techniques
1. Message Passing
2. Sockets
3. Named pipes
CMenu newMenu;
newMenu.LoadMenu (IDR_MENU1);
AfxGetMainWnd()->SetMenu( &newMenu );
AfxGetMainWnd()->DrawMenuBar();
newMenu.Detach ();
In the Release version of MFC, ASSERT does not evaluate the expression and thus will
not interrupt the program. If the expression must be evaluated regardless of environment,
use the VERIFY macro in place of ASSERT.
ASSERT and VERIFY are debug MACROS. ASSERT and VERIFY are same in debug
mode but in release mode, ASSERT does nothing whereas VERIFY evaluates the
expression but doesn't raise assertion. I had seen the code inside these macros and I don't
see any changes as such.
You can place calls in VERIFY, making sure that they will be made both in DEBUG and
RELEASE mode. If you do the same within an ASSERT, the call won't be made in
RELEASE.
// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system.
HDC hdc;
VERIFY( (hdc = ::GetDC(NULL)) != NULL);
::ReleaseDC(hdc);
The IDD enum of a dialog class contains the ID of dialog in the resource.
CMydlg dlg;
dlg.Create( CMydlg::IDD, 0 )
Instead of
CMydlg dlg;
Dlg.Create( IDD_MYDLG_DIALOG, 0 )
When MFC was initially developed a statement like the below one was not supported.
public:
static const DWORD IDD = IDD_MYDLG_DIALOG;
}
Also the trick of keeping an enum doesnt increase the memory size of object
What is serialization?
Five main steps are required to make a class serializable. They are listed below and
explained in the following sections:
1. Deriving your class from CObject (or from some class derived from CObject).
2. Overriding the Serialize member function.
3. Using the DECLARE_SERIAL macro in the class declaration.
4. Defining a constructor that takes no arguments.
5. Using the IMPLEMENT_SERIAL macro in the implementation file for your
class.
If you call Serialize directly rather than through the >> and << operators of CArchive,
the last three steps are not required for serialization.
The basic serialization protocol and functionality are defined in the CObject class. By
deriving your class from CObject (or from a class derived from CObject), as shown in
the following declaration of class CPerson, you gain access to the serialization protocol
and functionality of CObject.
The Serialize member function, which is defined in the CObject class, is responsible for
actually serializing the data necessary to capture an object's current state. The Serialize
function has a CArchive argument that it uses to read and write the object data. The
CArchive object has a member function, IsStoring, which indicates whether Serialize is
storing (writing data) or loading (reading data). Using the results of IsStoring as a guide,
you either insert your object's data in the CArchive object with the insertion operator
(<<) or extract data with the extraction operator (>>).
Consider a class that is derived from CObject and has two new member variables, of
types CString and WORD. The following class declaration fragment shows the new
member variables and the declaration for the overridden Serialize member function:
CString m_name;
WORD m_number;
1. Call your base class version of Serialize to make sure that the inherited portion of
the object is serialized.
2. Insert or extract the member variables specific to your class.
The insertion and extraction operators interact with the archive class to read and
write the data. The following example shows how to implement Serialize for the
CPerson class declared above:
You can also use the CArchive::Read and CArchive::Write member functions to read and
write large amounts of untyped data.
MFC requires a default constructor when it re-creates your objects as they are
deserialized (loaded from disk). The deserialization process will fill in all member
variables with the values required to re-create the object.
This constructor can be declared public, protected, or private. If you make it protected or
private, you help make sure that it will only be used by the serialization functions. The
constructor must put the object in a state that allows it to be deleted if necessary.
Note
If you forget to define a constructor with no arguments in a class that uses the
DECLARE_SERIAL and IMPLEMENT_SERIAL macros, you will get a "no default
constructor available" compiler warning on the line where the IMPLEMENT_SERIAL
macro is used.
The IMPLEMENT_SERIAL macro is used to define the various functions needed when
you derive a serializable class from CObject. You use this macro in the implementation
file (.CPP) for your class. The first two arguments to the macro are the name of the class
and the name of its immediate base class.
The third argument to this macro is a schema number. The schema number is essentially
a version number for objects of the class. Use an integer greater than or equal to 0 for the
schema number. (Don't confuse this schema number with database terminology.)
The MFC serialization code checks the schema number when reading objects into
memory. If the schema number of the object on disk does not match the schema number
of the class in memory, the library will throw a CArchiveException, preventing your
program from reading an incorrect version of the object.
If you want your Serialize member function to be able to read multiple versions — that
is, files written with different versions of the application — you can use the value
VERSIONABLE_SCHEMA as an argument to the IMPLEMENT_SERIAL macro.
For usage information and an example, see the GetObjectSchema member function of
class CArchive.
The following example shows how to use IMPLEMENT_SERIAL for a class, CPerson,
that is derived from CObject:
Once you have a serializable class, you can serialize objects of the class, as discussed in
the article Serialization: Serializing an Object.
1. how and when to create thread
2. can we call member function as thread
3. how to access the member fns of the class using the thread calling
COM/DCOM
4. How can would you create an instance of the object in COM? Well, it all
depends on your project. Start your answer from CoCreateInstance or
CoCreateInstanceEx, explain the difference between them. If interviewer is still
not satisfied, you’ll have to explain the whole kitchen behind the scenes,
including a difference between local server and inproc server, meaning and
mechanism of class factory, etc. You may also mention other methods of object
creation like CoGetInstanceFromFile, but discussion will likely turn to discussion
of monikers then.
5. What happens when client calls CoCreateInstance? Again, all depends on the
level of detail and expertise of interviewer. Start with simple explanation of class
object and class factory mechanism. Further details would depend on a specific
situation.
6. What the limitations of CoCreateInstance? Well, the major problems with
CoCreateInstance is that it is only able to create one object and only on local
system. To create a remote object or to get several objects, based on single
CLSID, at the same time, one should use CoCreateInstanceEx.
7. What is aggregation? How can we get an interface of the aggregated object?
Aggregation is the reuse mechanism, in which the outer object exposes interfaces
from the inner object as if they were implemented on the outer object itself. This
is useful when the outer object would always delegate every call to one of its
interfaces to the same interface in the inner object. Aggregation is actually a
specialized case of containment/delegation, and is available as a convenience to
avoid extra implementation overhead in the outer object in these cases. We can
get a pointer to the inner interface, calling QueryInterface of the outer object with
IID of the inner interface.
8. C is aggregated by B, which in turn aggregated by A. Our client requested C.
What will happen? QueryInterface to A will delegate request to B which, in turn,
will delegate request for the interface to C. This pointer will be returned to the
client.
9. What is a moniker ? An object that implements the IMoniker interface. A
moniker acts as a name that uniquely identifies a COM object. In the same way
that a path identifies a file in the file system, a moniker identifies a COM object in
the directory namespace.
10. What’s the difference, if any, between OLE and COM? OLE is build on top of
COM. The question is not strict, because OLE was built over COM for years,
while COM as a technology was presented by Microsoft a few years ago. You
may mention also that COM is a specification, while OLE is a particular
implementation of this specification, which in today’s world is not exactly true as
well, because what people call COM today is likely implementation of COM spec
by Microsoft.
11. What’s the difference between COM and DCOM? Again, the question does
not require strict answer. Any DCOM object is yet a COM object (DCOM
extends COM) and any COM object may participate in DCOM transactions.
DCOM introduced several improvements/optimizations for distributed
environment, such as MULTI_QI (multiple QueryInterface()), security contexts
etc. DCOM demonstrated importance of surrogate process (you cannot run in-
proc server on a remote machine. You need a surrogate process to do that.)
DCOM introduced a load balancing.
12. What is a dual interface? Dual interface is one that supports both - IDispatch
interface and vtbl-based interface. Therefore, it might be used in scripting
environment like VBScript and yet to use power and speed of vtbl-based interface
for non-scripting environment. Discussion then may easily transform into
analyzing of dual interface problems - be prepared to this twist.
13. Can you have two dual interfaces in one class? Yes. You may have two dual
interfaces in one class, but only one of them may be default. The bottom line is
that you cannot work with two dual interfaces at the same time due to nature of
dual interface! To support two dual interfaces in VB you would write something
like:
14. dim d1 as IDualInterface1
15. dim d2 as IDualInterface2
16. set d1 = new MyClassWithTwoDuals
17. set d2 = d1
Database Administrator :- A person (or group of people) responsible for the maintenance
and performance of a database and responsible for the planning, implementation,
configuration, and administration of relational database management systems.
Data Administrator :- The individual or organization responsible for the specification,
acquisition, and maintenance of data management software
and the design, validation, and security of files or databases. The DA is in charge of the
data dictionary and data model.
There are many locks available for the database system to have like
Intent Shared, Shared, Intent exclusive, exclusive and Shared Intent exclusive.
Locking granularity refers to the size and hence the number of locks used to ensure the
consistency of a database during multiple concurrent updates.
A transaction ensures that one or more operations execute as an atomic unit of work. If
one of the operations within a transaction fails, then all of them are rolled-back so that the
application is returned to its prior state. The boundaries that define a group of operations
done within a single transaction.
ACID means Atomic, Consistency, Isolation, Durability, so when any transaction happen
it should be Atomic that is it should either be complete or fully incomplete. There should
not be anything like Semi complete. The Database State should remain consistent after
the completion of the transaction. If there are more than one Transaction then the
transaction should be scheduled in such a fashion that they remain in Isolation of one
another.Durability means that Once a transaction commits, its effects will persist even if
there are system failures.
6. Explain the necessity of defining processing rights and responsibilities. How are
such responsibilities enforced?
One of the reason to define rights is the security in the database system. If any user is
allowed to define the data or alter the data then the database would just be of no use and
so processing rights and responsibilities are clearly defined in any database system. The
resposibilities are enforced using the table space provided by the database system.
Application-provided security :- It is much similar to the DBMS provided security but the
only difference is that its the duty of the programmer creating the application to provide
all the seurities so that the data is not mishandled.
If we reprocess the transaction then the database can be made to come to a state where
the database is consistent and so reprocessing the log can recover the database.
Reprocessing is not very feasible for a very simple reason that its very costly from time
point of view and requires lots of rework and many transaction are even rollback giving
more and more rework.
10. Why is it important to write to the log before changing the database values?
The most important objective to write the log before the database is changed is if there is
any need to rollback or rollforward any transaction then if the log are not present then the
rollback rollforward cannot be done accurately.