Friday 18 July 2014

Constructor/Destructor


1.       What is constructor?
A constructor in a class is a special type of method/function that is used to create and initialize object of a class. It is invoked automatically when the object of the class is created.
Constructor has the following properties. 
  • It has the same name as the class.
  • It is the only function in the class who does not have any return type. 
  •  It should be declared in public scope. 
  •  You cannot declare a constructor as virtual or static. 
  •  Constructor can neither be declared as const, volatile or const volatile. 
  •  Constructor can be overloaded. 
  •  If we do not declare constructor for our class then compiler provides default. 
  •  Complier provides default constructor only when we do not declare any. 
  •  We have declared a parameterized constructor in our class but we do not have constructor without parameter. If we do not pass arguments while creating object of that class, compiler tries to find default constructor which was not declared, hence we end up in error.

2.       What if constructor is declared in private scope?
If a constructor is declared in private scope then we will not be able to create object of that class outside of its scope. That means we can only create object inside the same class. Private constructor prevents to create any objects of the class.

3.       Can Abstract class have constructor?
Yes, you can either explicitly provide constructor to abstract class or if you don't, compiler will add default constructor of no argument in abstract class. This is true for all classes and its also applies on abstract class.

4.       What is copy constructor?
A copy constructor is a special constructor in the C++ programming language for creating a new object as a copy of an existing object. The first argument of such a constructor is a reference to an object of the same type as is being constructed, which might be followed by parameters of any type. Normally the compiler automatically creates a copy constructor for each class (known as a default copy constructor) but for special cases the programmer creates the copy constructor, known as a user-defined copy constructor. In such cases, the compiler does not create one. Hence, there is always one copy constructor that is either defined by the user or by the system.

 5.       What are the scenarios when a copy constructor is called?
  •  When an object is created from another object during initialization ( Class a = b )
  • When an object is created from another object as a parameter to a constructor (Class a(b))  
  • When an object is passed by value as an argument to a function e.g. fun(class a)  
  •  When an object is returned from a function    e.g.  fun () { .. return (a) ; }
  • When an exception is thrown using object type e.g.   … throw a; 
 
6.     What is the difference between shallow copy and deep copy?
Shallow Copy:

Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the reference addresses are copied i.e., only the memory address is copied.

Deep Copy:
A deep copy copies all fields, and make copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copies along with the object to which it refers.

http://www.jusfortechies.com/java/core-java/deepcopy_and_shallowcopy.php




7.  Can a copy constructor accept an object of the same class as parameter, instead of reference of the object? 
 No, it is specified in the definition of the copy constructor itself. It should generate an error if a programmer specifies a copy constructor with a first argument that is an object and not a reference. 

Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...

((You would have infinite recursion because "to make a copy, you need to make a copy")

C++ Classes



  1. What is an abstract class and how is it different from a normal class, give a scenario where you would use one over the another
An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration.
A normal class is a complete class where as abstract class is not a complete class, you can declare the contract as per the requirement in incomplete class, later you can fulfill the contract as defined. Loose coupling is provided by abstract class but abstract class is not 100% abstract that’s the reason Interface concept came into the picture.
·         Abstract classes cannot not be instantiated.
·         Abstract classes can be used to represent generic types like Animal
·         Abstract class can be extended by a concrete class in such a case, it must implement all the abstract methods of the abstract class that it is extending, if not, then it this class must be marked as abstract.
·         Abstract class can have abstract as well as non abstract methods.

  1. What is v-table?
To implement virtual functions, C++ uses a special form of late binding known as the virtual table. The virtual table is a lookup table of functions used to resolve function calls in a dynamic/late binding manner. The virtual table sometimes goes by other names, such as “vtable”, “virtual function table”, “virtual method table”, or “dispatch table”.
Because knowing how the virtual table works is not necessary to use virtual functions, this section can be considered optional reading.
The virtual table is actually quite simple, though it’s a little complex to describe in words. First, every class that uses virtual functions (or is derived from a class that uses virtual functions) is given it’s own virtual table. This table is simply a static array that the compiler sets up at compile time. A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this table is simply a function pointer that points to the most-derived function accessible by that class.
Second, the compiler also adds a hidden pointer to the base class, which we will call *__vptr. *__vptr is set (automatically) when a class instance is created so that it points to the virtual table for that class. Unlike the *this pointer, which is actually a function parameter used by the compiler to resolve self-references, *__vptr is a real pointer. Consequently, it makes each class object allocated bigger by the size of one pointer. It also means that *__vptr is inherited by derived classes, which is important.

  1. Will abstract class create virtual table or not?
yes v table is created but the corresponding entry for pure virtual function will be NULL.
Hence at runtime when we will check if the vtable will have any NULL entries the corresponding class will not be allowed to instantiate

  1. Why an abstract class can not be instantiated ?
Abstract class cannot instantiate means it cannot create a object!
Lets say a Shape abstract class, has triangle and circle derived classes.
You cannot have a object which is just a shape, it MUST BE either a triangle or a circle..
The reason for abstract class is to put this MUST BE condition!
I think it could be in two aspects.
First, from the perspective of philosophy, abstract class could not represent a real object. Say if someone asks you to buy a fruit, but don't tell you which kind of fruit, nothing could be bought.
Second, supposing an abstract class can be instanced, then the compiler needs to know how to handle a symbol like virtual void foo()=0; Here the symbole foo doesn't have a body, so compiler cannot put it in .text section, therefore it doesn't have address, just a null symbol. Further more, compiler also needs to ensure that no function calls is made to foo(). So a class has an instance but some of its methods cannot be accessed (we cannot just force all pure virtual functions must be declared as private), what it looks like? A black hole in language.

  1. Are inline virtual member functions ever actually inlined?
Occasionally...
When the object is referenced via a pointer or a reference, a call to a virtual function cannot be inlined, since the call must be resolved dynamically. Reason: the compiler can't know which actual code to call until run-time (i.e., dynamically), since the code may be from a derived class that was created after the caller was compiled.
Therefore the only time an inline virtual call can be inlined is when the compiler knows the "exact class" of the object which is the target of the virtual function call. This can happen only when the compiler has an actual object rather than a pointer or reference to an object. I.e., either with a local object, a global/static object, or a fully contained object inside a composite.
Note that the difference between inlining and non-inlining is normally much more significant than the difference between a regular function call and a virtual function call. For example, the difference between a regular function call and a virtual function call is often just two extra memory references, but the difference between an inline function and a non-inline function can be as much as an order of magnitude (for zillions of calls to insignificant member functions, loss of inlining virtual functions can result in 25X speed degradation! [Doug Lea, "Customization in C++," proc Usenix C++ 1990]).
A practical consequence of this insight: don't get bogged down in the endless debates (or sales tactics!) of compiler/language vendors who compare the cost of a virtual function call on their language/compiler with the same on another language/compiler. Such comparisons are largely meaningless when compared with the ability of the language/compiler to "inline expand" member function calls. I.e., many language implementation vendors make a big stink about how good their dispatch strategy is, but if these implementations don't inline member function calls, the overall system performance would be poor, since it is inlining —not dispatching— that has the greatest performance impact.