Skip to main content

C++ Questions I

Q1. What is the output of printf ( “%d” ) ?

%d helps to read integer data type of a given variable.
When we write ( “%d”, x ) compiler will print the value of x assumed in the main but nothing after ( “%d” ) so the output will be a garbage value.

Q2. Explain the need for a virtual destructor.

Destructor for the base parts are invoked automatically.
We might delete a ptr to the base type that actually points to a derived object,  if we delete a ptr to base then the base class destructor is executed and the members of the base class are cleared up. If the object is a derived type then the behavior is undefined. To ensure that the proper destructor is invoked the destructor must be virtual in the base class.

Q3. What is Mutable keyword ?

Mutable keyword is the key to make exceptions to const objects.
Mutable data member is allowed to change during a const member function.
Mutable data member is never a const even when it is a member of a const object.
A const member function may change a mutable member.

Q4. Why is the size of an empty class not zero?

To ensure that the addresses of two different objects will be different. For the same reason, “new” always returns pointers to distinct objects. Consider:
class Empty { };
void f()
Empty a, b;
if (&a == &b) cout << “impossible: report error to compiler supplier”;
Empty* p1 = new Empty;
Empty* p2 = new Empty;
if (p1 == p2) cout << “impossible: report error to compiler supplier”;
There is an interesting rule that says that an empty base class need not be represented by a separate byte:
struct X : Empty {
int a;
// …
void f(X* p)
void* p1 = p;
void* p2 = &p->a;
if (p1 == p2) cout << “nice: good optimizer”;
This optimization is safe and can be most useful. It allows a programmer to use empty classes to represent very simple concepts without overhead. Some current compilers provide this “empty base class optimization”.

Q5. Why are member functions not virtual by default?

Because many classes are not designed to be used as base classes. Also, objects of a class with a virtual function require space needed by the virtual function call mechanism – typically one word per object. This overhead can be significant, and can get in the way of layout compatibility with data from other languages (e.g. C and Fortran).

Q6. Why are destructors not virtual by default?

Because many classes are not designed to be used as base classes. Virtual functions make sense only in classes meant to act as interfaces to objects of derived classes (typically allocated on a heap and accessed through pointers or references).
So when should I declare a destructor virtual? Whenever the class has at least one virtual function. Having virtual functions indicate that a class is meant to act as an interface to derived classes, and when it is, an object of a derived class may be destroyed through a pointer to the base. For example:
class Base {
// …
virtual ~Base();
class Derived : public Base {
// …
void f()
Base* p = new Derived;
delete p; // virtual destructor used to ensure that ~Derived is called
Had Base’s destructor not been virtual, Derived’s destructor would not have been called – with likely bad effects, such as resources owned by Derived not being freed.

Q7. Why don’t we have virtual constructors?

A virtual call is a mechanism to get work done given partial information. In particular, “virtual” allows us to call a function knowing only an interfaces and not the exact type of the object. To create an object you need complete information. In particular, you need to know the exact type of what you want to create. Consequently, a “call to a constructor” cannot be virtual.
Techniques for using an indirection when you ask to create an object are often referred to as “Virtual constructors”.
For example, here is a technique for generating an object of an appropriate type using an abstract class:
struct F { // interface to object creation functions
virtual A* make_an_A() const = 0;
virtual B* make_a_B() const = 0;
void user(const F& fac)
A* p = fac.make_an_A(); // make an A of the appropriate type
B* q = fac.make_a_B(); // make a B of the appropriate type
// …
struct FX : F {
A* make_an_A() const { return new AX(); } // AX is derived from A
B* make_a_B() const { return new BX(); } // BX is derived from B
struct FY : F {
A* make_an_A() const { return new AY(); } // AY is derived from A
B* make_a_B() const { return new BY(); } // BY is derived from B
int main()
FX x;
FY y;
user(x); // this user makes AXs and BXs
user(y); // this user makes AYs and BYs
user(FX()); // this user makes AXs and BXs
user(FY()); // this user makes AYs and BYs
// …
This is a variant of what is often called “the factory pattern”. The point is that user() is completely isolated from knowledge of classes such as AX and AY.

Q8. Can I call a virtual function from a constructor?

Yes, but be careful. It may not do what you expect. In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
using namespace std;
class B {
B(const string& ss) { cout << “B constructor\n”; f(ss); }
virtual void f(const string&) { cout << “B::f\n”;}
class D : public B {
D(const string & ss) :B(ss) { cout << “D constructor\n”;}
void f(const string& ss) { cout << “D::f\n”; s = ss; }
string s;
int main()
D d(“Hello”);
the program compiles and produce
B constructor
D constructor
Note not D::f. Consider what would happen if the rule were different so that D::f() was called from B::B(): Because the constructor D::D() hadn’t yet been run, D::f() would try to assign its argument to an uninitialized string s. The result would most likely be an immediate crash.
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.

Q9. Is there a “placement delete”?

No, but if you need one you can write your own.
Consider placement new used to place objects in a set of arenas
class Arena {
void* allocate(size_t);
void deallocate(void*);
// …
void* operator new(size_t sz, Arena& a)
return a.allocate(sz);
Arena a1(some arguments);
Arena a2(some arguments);
Given that, we can write
X* p1 = new(a1) X;
Y* p2 = new(a1) Y;
Z* p3 = new(a2) Z;
// …
But how can we later delete those objects correctly? The reason that there is no built-in “placement delete” to match placement new is that there is no general way of assuring that it would be used correctly. Nothing in the C++ type system allows us to deduce that p1 points to an object allocated in Arena a1. A pointer to any X allocated anywhere can be assigned to p1.
However, sometimes the programmer does know, and there is a way:
template<class T> void destroy(T* p, Arena& a)
if (p) {
p->~T(); // explicit destructor call
Now, we can write:
If an Arena keeps track of what objects it holds, you can even write destroy() to defend itself against mistakes.
It is also possible to define a matching operator new() and operator delete() pairs for a class hierarchy.

Q10. Does “friend” violate encapsulation?

No. It does not. “Friend” is an explicit mechanism for granting access, just like membership. You cannot (in a  standard conforming program) grant yourself access to a class without modifying its source. For example:
class X {
int i;
void m(); // grant X::m() access
friend void f(X&); // grant f(X&) access
// …
void X::m() { i++; /* X::m() can access X::i */ }
void f(X& x) { x.i++; /* f(X&) can access X::i */ }


Popular posts from this blog

Exploring Node.js Internals

I found a great article explaining Node JS internals, must read : Some other articles : Introduction to Node.js Being an official website, explains what Node.js is, as well as its package managers, and lists web frameworks built on top of it. “ JavaScript & Node.js ”,  The Node Beginner Book This book by  Manuel Kiessling  does a fantastic job of explaining Node.js, after warning that JavaScript in the browser is not the same as the one in Node.js, even though both are written in the same language. Beginning Node.js This beginner book goes beyond an explanation of the runtime. It teaches about packages and streams and creating a web server with the Express framework. LibUV This is the official documentation of the supporting C++ code of the Node.js runtime. V8 This is the official documentation of the JavaScript engine that makes it possible to write Node.js with JavaScript.

Hibernate Object Conversations

Session methods to use for object conversations Save() A new instance being attached to the session. An insert will be scheduled. Update() Call Update to make a transient object persistent again. It will force a SQL update on the transient object. This is because Hibernate does not know whether the object is dirty or not and to be safe by default schedules an update. This method will throw an exception, if the entity is already registered with the session. - NonUniqueObjectException is thrown. saveOrUpdate() Either a save or an update will be called based on whether the identifier exists or not. No identifier - save is called, else update is called. Or for a better understanding, if the object is transient, then a save is called, if the object is persistent, then an update is called. Reattaching an unmodified instance - If you know for sure that an object is not modified and you just want to make it persistent again - Session.lock(item, LockMode.No