Difference between revisions of "C++ interview"

From Hawk Wiki
Jump to: navigation, search
Line 1: Line 1:
 
==Explicit constructor==
 
==Explicit constructor==
<code class="c">
+
<pre class="c">
 
class Array
 
class Array
 
{
 
{
Line 39: Line 39:
  
 
A thing of beauty.
 
A thing of beauty.
</code>
+
</pre>
 
===Private Inheritance===
 
===Private Inheritance===
 
Private inheritance is like making a composition.<br>
 
Private inheritance is like making a composition.<br>
 
One advantage to using protected/private inheritance instead of composition is that the derived class has access to protected members in the parent class. However this is kind of a double-edged sword, as it becomes easier to misuse the class.
 
One advantage to using protected/private inheritance instead of composition is that the derived class has access to protected members in the parent class. However this is kind of a double-edged sword, as it becomes easier to misuse the class.
<code class="c">
+
<pre class="c">
 
class Motherboard {};
 
class Motherboard {};
  
Line 58: Line 58:
 
   Motherboard mobo;
 
   Motherboard mobo;
 
};
 
};
</code>
+
</pre>
  
 
===Virtual Functions===
 
===Virtual Functions===
Line 65: Line 65:
 
===Virtual inheritance===
 
===Virtual inheritance===
 
To avoid ambiguous call of the same 2 levels higher base class. Declare virtual to say that the 2 levels higher base class is the same shared one.
 
To avoid ambiguous call of the same 2 levels higher base class. Declare virtual to say that the 2 levels higher base class is the same shared one.
<code class="c">
+
<pre class="c">
 
class Animal {
 
class Animal {
 
  public:
 
  public:
Line 85: Line 85:
 
class Bat : public Mammal, public WingedAnimal {
 
class Bat : public Mammal, public WingedAnimal {
 
};
 
};
</code>
+
</pre>
 
To avoid ambiguous between inherited WingedAnimal::Animal and Mammal:Animal
 
To avoid ambiguous between inherited WingedAnimal::Animal and Mammal:Animal
 
From the code above.Animal instance is unambiguous,and we can call Bat::eat().
 
From the code above.Animal instance is unambiguous,and we can call Bat::eat().
  
 
===Virtual const===
 
===Virtual const===
<code class="c">
+
<pre class="c">
 
class Base
 
class Base
 
{
 
{
Line 118: Line 118:
 
     return 0;
 
     return 0;
 
}
 
}
</code>
+
</pre>
 
The example above base class evel() will be called.
 
The example above base class evel() will be called.
 
In your Derived class, the prototype for eval doesn't match the one for the virtual function in Base. So it won't override the virtual function.
 
In your Derived class, the prototype for eval doesn't match the one for the virtual function in Base. So it won't override the virtual function.
 
If you add the const for Derived::eval(), you should get virtual behavior.
 
If you add the const for Derived::eval(), you should get virtual behavior.
 +
===ArrayList Vs LinkedList===
 +
ArrayList: fast random access<br>
 +
slow at delete<br>
 +
memory fill up issue<br>
 +
LinkedList: slow random access<br>
 +
quick delete<br>
 +
no memory fill up issue<br>
 +
complex data structure<br>

Revision as of 23:07, 3 April 2012

Explicit constructor

class Array
{
public:
    Array(size_t count);
    // etc.
};

This seems innocent enough until you realize that you can do this:

Array array = 123;

Well that’s ugly but hardly something to get excited about, or is it? This is known as an implicit conversion. The trouble is that it can occur in more insidious places. Consider the following function:

void UseArray(const Array& array);

Because the compiler will attempt to find an implicit conversion, the following code compiles just find:

UseArray(123);

Yikes! That’s terrible. First there is the problem of code clarity. What does this mean? 
Secondly, because the implicit conversion involves calling the Array constructor, presumably enough storage is being allocated for a new Array object, 
not to mention the memory reserved for 123 elements contained in the array. Surely this is not what the programmer intended!?

All of these subtleties can be avoided by making the Array constructor explicit:

class Array
{
public:
    explicit Array(size_t size);
    // etc.
};

Now a programmer needs to be explicit about her use of the Array constructor.

Array array(123);
UseArray(Array(123));

A thing of beauty.

Private Inheritance

Private inheritance is like making a composition.
One advantage to using protected/private inheritance instead of composition is that the derived class has access to protected members in the parent class. However this is kind of a double-edged sword, as it becomes easier to misuse the class.

class Motherboard {};

// this makes a "has a" relationship
class Computer : private Motherboard
{
};

// this makes a similar "has a" relationship
//  this approach is aka "composition"
class Computer
{
private:
  Motherboard mobo;
};

Virtual Functions

If the function is designated virtual in the base class then the derived class' function would be called (if it exists). If it is not virtual, the base class' function would be called. To be short, virtual functions will have lowest priority to be called.

Virtual inheritance

To avoid ambiguous call of the same 2 levels higher base class. Declare virtual to say that the 2 levels higher base class is the same shared one.

class Animal {
 public:
  virtual void eat();
};
 
// Two classes virtually inheriting Animal:
class Mammal : public virtual Animal {
 public:
  virtual void breathe();
};
 
class WingedAnimal : public virtual Animal {
 public:
  virtual void flap();
};
 
// A bat is still a winged mammal
class Bat : public Mammal, public WingedAnimal {
};

To avoid ambiguous between inherited WingedAnimal::Animal and Mammal:Animal From the code above.Animal instance is unambiguous,and we can call Bat::eat().

Virtual const

class Base
{
public:
    virtual void eval() const
    {
        std::cout<<"Base Const Eval\n";
    }
};

class Derived:public Base
{
public:
    void eval()
    {
        std::cout<<"Derived Non-Const Eval\n";
    }
};
int main()
{

    Derived d;
    Base* pB=&d;

    pB->eval(); //This will call the Base eval()

    return 0;
}

The example above base class evel() will be called. In your Derived class, the prototype for eval doesn't match the one for the virtual function in Base. So it won't override the virtual function. If you add the const for Derived::eval(), you should get virtual behavior.

ArrayList Vs LinkedList

ArrayList: fast random access
slow at delete
memory fill up issue
LinkedList: slow random access
quick delete
no memory fill up issue
complex data structure