C and C++ and SOLID Interview Questions II

  1. What is the error in the code below and how should it be corrected?

    my_struct_t *bar;
    /* ... do stuff, including setting bar to point to a defined my_struct_t object ... */
    memset(bar, 0, sizeof(bar))

    The last argument to memset should be sizeof(*bar), not sizeof(bar). sizeof(bar) calculates the size of bar (i.e., the pointer itself) rather than the size of the structure pointed to by bar.

    The code can therefore be corrected by using sizeof(*bar) as the last argument in the call to memset.
  2. What will i and j equal after the code below is executed? Explain your answer.

    int i = 5;
    int j = i++;
    After the above code executes, i will equal 6, but j will equal 5.

    Understanding the reason for this is fundamental to understanding how the unary increment (++) and decrement (--) operators work in C++. When these operators precede a variable, the value of the variable is modified first and then the modified value is used.

  3. Consider the two code snippets below for printing a vector. Is there any advantage of one vs. the other? Explain.

    Option 1:

    vector vec;
    /* ... .. ... */
    for (auto itr = vec.begin(); itr != vec.end(); itr++) {

    Option 2:

    vector vec;
    /* ... .. ... */
    for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
    • Both do the same thing.
    • The second option is better from a performance standpoint.

    • The post-increment operator (i.e., itr++) is more expensive than pre-increment operator (i.e., ++itr).
    • The underlying implementation of the post-increment operator makes a copy of the element before incrementing it and then returns the copy.
  4. Implement a template function IsDerivedFrom() that takes
    class C and class P as template parameters. It should return true when
    class C is derived from class P and false otherwise.
    • template<typename D, typename B>
    • class IsDerivedFromHelper
    • {
    •    class No { };
    •    class Yes { No no[3]; };

    •    static Yes Test( B* );
    •    static No Test( ... );

    • public:
    •    enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };


    • template <class C, class P>
    • bool IsDerivedFrom() {
    • return IsDerivedFromHelper<C, P>::Is;
    • }

    This is already a part of the C++11 std library (std::is_base_of) or part of the boost library for C++ (boost::is_base_of). Even an interviewee with only passing knowledge should write something similar to this, mostly likely involving a helper class.
  5. Implement a template boolean IsSameClass() that takes class A and B as template parameters. It should compare class A and B and return false when they are different classes and true if they are the
    same class.
    • template <typename T, typename U>
    • struct is_same
    • {
    •    static const bool value = false;
    • };

    • template <typename T>
    • struct is_same<T, T>
    • {
    •   static const bool value = true;
    • };

    • template <class A, class B>
    • bool IsSameClass() {
    • return is_same<A, B>::value;
    • }
  6. Is it possible to have a recursive inline function?
    Although you can call an inline function from within itself, the compiler will not generate inline code since the compiler cannot determine the depth of recursion at compile time.
  7. When you should use virtual inheritance?
    • While it’s ideal to avoid virtual inheritance altogether (you should know how your class is going to be used) having a solid understanding of how virtual inheritance works is still important: So when you have a class (class A) which inherits from 2 parents (B and C), both of which share a parent (class D), as demonstrated below:

    • Image Upload 1

    • If you don’t use virtual inheritance in this case, you will get two copies of D in class A: one from B and one from C. To fix this you need to change the declarations of classes C and B to be virtual, as follows:

    • Image Upload 2
  8. Is there a difference between class and struct?
    The only difference between a class and struct are the access modifiers.

    • Struct members are public by default.
    • Class members are private.

    It is good practice to use classes when you need an object that has methods and structs when you have a simple data object.
  9. What is the output of the following code:

    Image Upload 3
    The above will output 8, since:

    (1+3)[a] is the same as a[1+3] == 5

    a[0] == 1

    (a + 1)[2] is the same as a[3] == 4

    This question is testing pointer arithmetic knowledge, and the magic behind square brackets with pointers.

    While some might argue that this isn’t a valuable question as it appears to only test the capability of reading C constructs, it’s still important for a candidate to be able to work through it mentally; it’s not an answer they’re expected to know off the top of their head, but one where they talk about what conclusion they reach and how.
  10. What is the output of the following code:

    Image Upload 4
    The above will output:

    from A

    from A

    from Base

    The important thing to note here is the order of destruction of classes and how Base’s method reverts back to its own implementation once A has been destroyed.
  11. Explain the volatile and mutable keywords
    The volatile keyword informs the compiler that a variable will be used by multiple threads. Variables that are declared as volatile will not be cached by the compiler to ensure the most up-to-date value is held.

    The mutable keyword can be used for class member variables. Mutable variables are allowed to change from within const member functions of the class.
  12. How many times will this loop execute? Explain your answer.
    If you said 300, you would have been correct if i had been declared as an int. However, since i was declared as an unsigned char, the correct answer is that this code will result in an infinite loop.

    Here’s why:

    The expression 2 * half_limit will get promoted to an int (based on C++ conversion rules) and will have a value of 300. However, since i is an unsigned char, it is re-repsented by an 8-bit value which, after reaching 255, will overflow (so it will go back to 0) and the loop will therefore go on forever.
  13. What is virtual function?
    When derived class overrides the base class method by redefining the same function, then if client wants to access redefined the method from derived class through a pointer from base class object, then you must define this function in base class as virtual function.
  14. What is a "pure virtual" member function?
    The abstract class whose pure virtual method has to be implemented by all the classes which derive on these. Otherwise it would result in a compilation error. This construct should be used when one wants to ensure that all the derived classes implement the method defined as pure virtual in base class.
  15. Explain the IS A and HAS A class relationships. How would you implement each in a class design?
    A specialized class "is" a specialization of another class and, therefore, has the IS A relationship with the other class. So you use inheritance.

    For HAS A :This relationship is best implemented by embedding an object of  one class in another class; example:  the Salary class object would be embedded in the Employee class.
  16. When is a template a better solution than a base class?
    When you are designing a generic class to contain or otherwise manage objects of other types, when the format and behavior of those other types are unimportant to their containment or management, and particularly when those other types are unknown (thus, the generality) to the designer of the container or manager class.
  17. In OOP what does polymorphism mean?
    Polymorphism occurs when there is a hierarchy of classes and they are related by inheritance. In C++ means that a call to a member function will cause a different function to be executed.
  18. What does SOLID stand for?
    • Single responsibility
    • Open-closed
    • Liskov substitution
    • Interface segregation 
    • Dependency inversion.
  19. What is Single Responsibility?
    The idea that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.
  20. What is Open Closed?
    Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification; that is, such an entity can allow its behavior to be extended without modifying its source code.
  21. What is the Liskov substitution principal?
    In a computer program, if S is a sub-type of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).
  22. What is Interface segregation principle?
    States that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.
  23. What is Dependency inversion?
    refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details.
  24. What are the two principals of dependency inversion?
    • A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
    • B. Abstractions should not depend on details. Details should depend on abstractions.
Card Set
C and C++ and SOLID Interview Questions II
More C++ Questions.