2.16.  Review Questions

[ fromfile: classes-questions.xml id: classes-questions ]

  1. Describe at least one difference between a class and a struct.

      Basically, they are the same except for the default access level of members (public for struct, private for class). Classes and structs can both have member functions, constructors, etc. However, as soon as you add member functions and access specifiers, a struct becomes more "class-like".

  2. How does class scope differ from block scope?

      Class scope is accessible inside other class members. block scope is accessible only inside that block.

  3. Describe two situations where it is OK to use friend functions.

      When enforcing creational rules, or for global operator functions.

  4. How does a static data member differ from a non-static data member?

     

    A static data member of a class T is created and initialized when the program begins execution. It exists even if no T objects have been created. It is shared by all existing T objects. It is destroyed when the program terminates.

    A non-static data member of a class T is created and initialized only when a T object is created. It belongs exclusively to one object. It is destroyed when that object is destroyed.

  5. What is the difference between a static member function and a non-static member function?

     

    A static member function of a class T cannot access any non-static data members of T. If it is public, it can be accessed by client code with the scope resolution operator T::, or through an object/pointer/reference.

    A non-static member function of a class T can access any data members of T. If it is public, it can be accessed by client code through an object (directly, or indirectly via pointer/reference).

  6. What does it mean to declare a member function to be const?

      The member function is not allowed to change any member of *this.

  7. Explain what would happen (and why) if a class T could have a copy constructor with the following prototype?

     T::T(T other); 

     

    This would be a compile error. If the compiler allowed that version of the copy constructor, then imagine what would happen during a pass-by-value. Because this copy constructor takes a value parameter, it would need to call itself to pass its own parameter, and this would result in an infinite recursion.

  8. Some of the lines marked in Example 2.31 have errors. There are multiple choices for the answers shown in Example 2.32.

    Example 2.31. src/quizzes/constquiz.cpp

    #include <iostream>
    
    class Point {
      public:
      Point(int px, int py)
           : m_X(px), m_Y(py) {}    1
    
        void set(int nx, int ny) {
            m_X = nx;
            m_Y = ny;
        }
        void print() const {
            using namespace std;
            cout << "[" << m_X << "," << m_Y << "]";
            m_printCount ++;        2
        }
      private:
        int m_X, m_Y;
        int m_printCount;           3
    };
    
    int main() {
        Point p(1,1);
        const Point q(2,2);
        p.set(4,4);                 4
        p.print();
        q.set(4,4);                 5
        q.print();                  6
        return 0;
    }
    

    1

    _________

    2

    _________

    3

    _________

    4

    _________

    5

    _________

    6

    _________

    <include src="src/quizzes/constquiz.cpp" href="src/quizzes/constquiz.cpp" id="constquiz1cpp" mode="cpp"/>


    Example 2.32. src/quizzes/constquiz-questions.txt

    1. What are the errors?
        a. Not allowed here.
        b. m_pointCount is missing here causing a compiler error.
        c. Missing semicolon in the {}.
        d. m_pointCount is missing here causing a runtime error.
        e. Nothing is wrong.
    
    2. What are the errors?
        a. Nothing is wrong.
        b. m_printCount needs to be const.
        c. m_printCount needs to be explicit.
        d. Compiler error - can't change m_printCount.
        e. m_printCount needs to be volatile.
    
    3. What is the error?
        a. Nothing is wrong.
        b. m_printCount needs to be volatile.
        c. m_printCount needs to be const.
        d. m_printCount needs to be mutable.
        e. m_printCount needs to be explicit.
    
    4. What are the errors?
        a. Can't call const member.
        b. Can't call non-const member.
        c. Nothing is wrong.
        d. Set needs to be const.
        e. Set needs to be volatile.
    
    5. What are the errors?
        a. Can't call const member.
        b. Can't call non-const member.
        c. Set needs to be volatile.
        d. q needs to be non-const.
        e. Set needs to be volatile.
    
    6. What is the error?
        a. Nothing is wrong.
        b. Can't call non-const member.
        c. print needs to be const.
        d. q needs to be explicit.
        e. Can't call const member.
    

    <include src="src/quizzes/constquiz-questions.txt" href="src/quizzes/constquiz-questions.txt" mode="txt" id="constquiz1-questions"/>


  9. Find the errors in Example 2.33 and answer the questions in Example 2.34.

    Example 2.33. src/quizzes/statics-quiz.cpp

    // wadget.h:
    
    class Wadget {
    public:
        Wadget(double a, double b);
        void print();
        static double calculation();
        static int wadgetCount();
    
    private:
        double m_d1, m_d2;
        static int m_wadgetCount;
    };
    
    // wadget.cpp:
    
    Wadget::Wadget(double a, double b)
    :  m_d1(a), m_d2(b) {
        m_wadgetCount ++;
    }
    
    static int wadgetCount() {
        return m_wadgetCount;
    }
    
    double Wadget::calculation() {
        return d1*d2 + m_wadgetCount;
    }
    [ . . . . ]
    

    <include src="src/quizzes/statics-quiz.cpp" link="false" id="statics-quizcpp" mode="cpp"/>


    Example 2.34. src/quizzes/statics-quiz.txt

    1. There are a number of problems with the code above.
    The first is that it will not link, because of a missing
    definition of m_wadgetCount. How do we fix that problem?
    
        a. wadget.h inside class definition:
            static int m_wadgetCount = 0;
        b. wadget.h: outside class definition:
            static int Wadget::m_wadgetCount = 0;
        c. wadget.cpp: top of file
            int Wadget::m_wadgetCount = 0;
        d. wadget.cpp: top of file
            static int Wadget::m_wadgetCount = 0;
        e. wadget.cpp member initialization list:
            Wadget::Wadget()
            :  m_d1(a), m_d2(b), m_wadgetCount(0)
                { m_wadgetCount ++; }
    
    }
    
    
    2. For the declaration of
          static int Wadget::wadgetCount()
       What does the static here mean?
    
       a. function must be defined in a .cpp file
       b. function can only be called on static objects
       c. function must be called with Wadget:: scope resolution
       d. function name has file scope
       e. function can only access static members
    
    
    3. For the definition of
          static int Wadget::wadgetCount()
       What does the static here mean?
       a. function can only access static members
       b. function can only be called on static objects
       c. function must be called with Wadget:: scope resolution
       d. function name is exported to the linker
       e. function name is not exported to the linker
    
    
    4. What can we say about the definition of Wadget::calculation()?
    
       a. d1 and d2 are not accessible from the static method
       b. missing a 'static' before the function definition
       c. there is nothing wrong with this.
       d. both a and b
       e. function name is not exported to the linker (error)
    

    <include src="src/quizzes/statics-quiz.txt" href="src/quizzes/statics-quiz.txt" id="statics-quiz.txt" mode="text"/>