Difference between revisions of "C++ interview"

From Hawk Wiki
Jump to: navigation, search
(Private Inheritance)
(=c++ const pointer / pointer to const data)
 
(36 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
==Explicit constructor==
 
==Explicit constructor==
<pre>
+
The reason you might want to do this is to <b>avoid accidental construction</b> that can hide bugs.<br>
 +
example:<br>
 +
<li>You have a MyString(int size) class that constructs a string of the given size. You have a function print(MyString &), and you call it with print(3). You expect it to print "3", but it prints an empty string of length 3 instead.<br>
 +
Another example:<br>
 +
<pre class="brush:c">
 
class Array
 
class Array
 
{
 
{
Line 7: Line 11:
 
     // etc.
 
     // etc.
 
};
 
};
 +
</pre>
  
 
This seems innocent enough until you realize that you can do this:
 
This seems innocent enough until you realize that you can do this:
Line 13: Line 18:
  
 
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:
 
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:
 
+
<pre class="brush:c">
 
void UseArray(const Array& array);
 
void UseArray(const Array& array);
 
+
</pre>
 
Because the compiler will attempt to find an implicit conversion, the following code compiles just find:
 
Because the compiler will attempt to find an implicit conversion, the following code compiles just find:
 
+
<pre class="brush:c">
 
UseArray(123);
 
UseArray(123);
 
+
</pre>
 
Yikes! That’s terrible. First there is the problem of code clarity. What does this mean?  
 
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,  
 
Secondly, because the implicit conversion involves calling the Array constructor, presumably enough storage is being allocated for a new Array object,  
Line 25: Line 30:
  
 
All of these subtleties can be avoided by making the Array constructor explicit:
 
All of these subtleties can be avoided by making the Array constructor explicit:
 
+
<pre class="brush:c">
 
class Array
 
class Array
 
{
 
{
Line 32: Line 37:
 
     // etc.
 
     // etc.
 
};
 
};
 
+
</pre>
 
Now a programmer needs to be explicit about her use of the Array constructor.
 
Now a programmer needs to be explicit about her use of the Array constructor.
 
+
<pre class="brush:c">
 
Array array(123);
 
Array array(123);
 
UseArray(Array(123));
 
UseArray(Array(123));
 +
</pre>
 +
A thing of beauty.
  
A thing of beauty.
 
</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="Cpp">
+
<pre class="brush:c">
 
class Motherboard {};
 
class Motherboard {};
  
Line 58: Line 63:
 
   Motherboard mobo;
 
   Motherboard mobo;
 
};
 
};
</code>
+
</pre>
  
 
===Virtual Functions===
 
===Virtual Functions===
 +
When virtual function in based class has been called, it will find the most derived version to call.<br>
 
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.
 
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.
 
To be short, virtual functions will have lowest priority to be called.
 +
 
===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.
<pre>
+
<pre class="brush:c">
 
class Animal {
 
class Animal {
 
  public:
 
  public:
Line 88: Line 95:
 
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===
<pre>
+
<pre class="brush:c">
 
class Base
 
class Base
 
{
 
{
Line 118: Line 126:
 
}
 
}
 
</pre>
 
</pre>
The example above base class evel() will be called.
+
Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called.<br>
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.
+
Const and non-const are 2 different functions <br>
 +
The example above base class evel() will be called.<br>
 +
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.<br>
 
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.
 +
===Why destructor needs to be virtual===
 +
http://blogs.msdn.com/b/oldnewthing/archive/2004/05/07/127826.aspx
 +
 +
===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>
 +
===Pointer size===
 +
32 bit system: sizeof(char) == 1.<br>
 +
 +
In practice, pointers will be size 2 on a 16-bit system (if you can find one), 4 on a 32-bit system, and 8 on a 64-bit system, but there's nothing to be gained in relying on a given size.
 +
===Program memory===
 +
 +
The computer program memory is organized into the following:<br>
 +
Data Segment (Data + BSS + Heap)<br>
 +
<b>Stack</b><br>
 +
Code segment<br>
 +
<b>Data</b><br>
 +
The data area contains global and static variables used by the program that are explicitly initialized with a value. This segment can be further classified into a read-only area and read-write area. For instance, the string defined by char s[] = "hello world" in C and a C statement like int debug=1 outside the "main" would be stored in initialized read-write area. And a C statement like const char* string = "hello world" makes the string literal "hello world" to be stored in initialized read-only area and the character pointer variable string in initialized read-write area. Ex: both static int i = 10 and global int i = 10 will be stored in the data segment.<br>
 +
<b>BSS</b><br>
 +
The BSS segment, also known as uninitialized data, starts at the end of the data segment and contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code. For instance a variable declared static int i; would be contained in the BSS segment.
 +
<b>Heap</b><br>
 +
The heap area begins at the end of the BSS segment and grows to larger addresses from there. The heap area is managed by malloc, realloc, and free, which may use the brk and sbrk system calls to adjust its size (note that the use of brk/sbrk and a single "heap area" is not required to fulfill the contract of malloc/realloc/free; they may also be implemented using mmap to reserve potentially non-contiguous regions of virtual memory into the process' virtual address space). The heap area is shared by all shared libraries and dynamically loaded modules in a process.<br>
 +
<b>Stack</b><br>
 +
The stack area traditionally adjoined the heap area and grew the opposite direction; when the stack pointer met the heap pointer, free memory was exhausted. (With modern large address spaces and virtual memory techniques they may be placed almost anywhere, but they still typically grow in opposite directions.)<br>
 +
The stack area contains the program stack, a LIFO structure, typically located in the higher parts of memory. On the standard PC x86 computer architecture it grows toward address zero; on some other architectures it grows the opposite direction. A "stack pointer" register tracks the top of the stack; it is adjusted each time a value is "pushed" onto the stack. The set of values pushed for one function call is termed a "stack frame"; A stack frame consists at minimum of a return address.<br>
 +
===C++ name hiding===
 +
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fname_hiding.htm
 +
===c++ const pointer / pointer to const data ===
 +
const keyword apply to the word to its left.<br >
 +
Const Data:<br>
 +
const type* variable;<br>
 +
type const * variable;<br>
 +
Const pointer Address:<br>
 +
type * const variable = some memory address;
 +
 +
==Q&A==
 +
<li>Q:What is the difference between %d and %*d in c language? <br>
 +
A: %d give the original value of the variable and %*d give the address <br>
 +
<li>Q:What is the difference between "calloc(...)" and "malloc(...)"?<br>
 +
calloc(...) allocates an array in memory with elements initialized. But malloc won't init elements.<br>
 +
<li>Q:What is the difference between "printf(...)" and"sprintf(...)"?<br>
 +
A:sprintf(...) writes data to the character array whereas printf(...) writes data to the
 +
standard output device.<br>
 +
<li>Q:What does static variable mean?<br>
 +
A:There are 3 main uses for the static.<br>
 +
1. If you declare within a function:It retains the value between function calls<br>
 +
2.If it is declared for a function name:By default function is extern..so it will be visible from other files if the function declaration is as static..it is invisible for the outer files<br>
 +
3. Static for global variables:By default we can use the global variables from outside files If it is static global..that variable is limited to with in the file<br>
 +
<li>Q:Difference between const char* p and char const* p?<br>
 +
A:see http://duramecho.com/ComputerInformation/WhyHowCppConst.html.<br>
 +
 +
<li>Q:assert funtion?<br>
 +
A:void assert (int expression);<br>
 +
example: assert (myInt!=NULL);<br>
 +
assert is used to abort the program execution if print_number is called with a null pointer as attribute. <br>
 +
 +
http://www.careerride.com/C++-Interview-questions-Answer.aspx

Latest revision as of 01:06, 24 January 2013

Explicit constructor

The reason you might want to do this is to avoid accidental construction that can hide bugs.
example:

  • You have a MyString(int size) class that constructs a string of the given size. You have a function print(MyString &), and you call it with print(3). You expect it to print "3", but it prints an empty string of length 3 instead.
    Another example:
    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

    When virtual function in based class has been called, it will find the most derived version to call.
    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;
    }
    

    Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called.
    Const and non-const are 2 different functions
    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.

    Why destructor needs to be virtual

    http://blogs.msdn.com/b/oldnewthing/archive/2004/05/07/127826.aspx

    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

    Pointer size

    32 bit system: sizeof(char) == 1.

    In practice, pointers will be size 2 on a 16-bit system (if you can find one), 4 on a 32-bit system, and 8 on a 64-bit system, but there's nothing to be gained in relying on a given size.

    Program memory

    The computer program memory is organized into the following:
    Data Segment (Data + BSS + Heap)
    Stack
    Code segment
    Data
    The data area contains global and static variables used by the program that are explicitly initialized with a value. This segment can be further classified into a read-only area and read-write area. For instance, the string defined by char s[] = "hello world" in C and a C statement like int debug=1 outside the "main" would be stored in initialized read-write area. And a C statement like const char* string = "hello world" makes the string literal "hello world" to be stored in initialized read-only area and the character pointer variable string in initialized read-write area. Ex: both static int i = 10 and global int i = 10 will be stored in the data segment.
    BSS
    The BSS segment, also known as uninitialized data, starts at the end of the data segment and contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code. For instance a variable declared static int i; would be contained in the BSS segment. Heap
    The heap area begins at the end of the BSS segment and grows to larger addresses from there. The heap area is managed by malloc, realloc, and free, which may use the brk and sbrk system calls to adjust its size (note that the use of brk/sbrk and a single "heap area" is not required to fulfill the contract of malloc/realloc/free; they may also be implemented using mmap to reserve potentially non-contiguous regions of virtual memory into the process' virtual address space). The heap area is shared by all shared libraries and dynamically loaded modules in a process.
    Stack
    The stack area traditionally adjoined the heap area and grew the opposite direction; when the stack pointer met the heap pointer, free memory was exhausted. (With modern large address spaces and virtual memory techniques they may be placed almost anywhere, but they still typically grow in opposite directions.)
    The stack area contains the program stack, a LIFO structure, typically located in the higher parts of memory. On the standard PC x86 computer architecture it grows toward address zero; on some other architectures it grows the opposite direction. A "stack pointer" register tracks the top of the stack; it is adjusted each time a value is "pushed" onto the stack. The set of values pushed for one function call is termed a "stack frame"; A stack frame consists at minimum of a return address.

    C++ name hiding

    http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fname_hiding.htm

    c++ const pointer / pointer to const data

    const keyword apply to the word to its left.
    Const Data:
    const type* variable;
    type const * variable;
    Const pointer Address:
    type * const variable = some memory address;

    Q&A

  • Q:What is the difference between %d and %*d in c language?
    A: %d give the original value of the variable and %*d give the address
  • Q:What is the difference between "calloc(...)" and "malloc(...)"?
    calloc(...) allocates an array in memory with elements initialized. But malloc won't init elements.
  • Q:What is the difference between "printf(...)" and"sprintf(...)"?
    A:sprintf(...) writes data to the character array whereas printf(...) writes data to the standard output device.
  • Q:What does static variable mean?
    A:There are 3 main uses for the static.
    1. If you declare within a function:It retains the value between function calls
    2.If it is declared for a function name:By default function is extern..so it will be visible from other files if the function declaration is as static..it is invisible for the outer files
    3. Static for global variables:By default we can use the global variables from outside files If it is static global..that variable is limited to with in the file
  • Q:Difference between const char* p and char const* p?
    A:see http://duramecho.com/ComputerInformation/WhyHowCppConst.html.
  • Q:assert funtion?
    A:void assert (int expression);
    example: assert (myInt!=NULL);
    assert is used to abort the program execution if print_number is called with a null pointer as attribute.
    http://www.careerride.com/C++-Interview-questions-Answer.aspx