CIS 330 Practice Final Exam Questions


Following are examples of questions and subjects you might find on the final exam.

  1. Find the significant errors in the following code:
    class Array {
    public:
        Array() : len(0) { data = NULL; }
        Array(int size) : len(size) { data = new int[len]; }
        Array(const Array & a) : len(a.len) {
            data = new int[len];
            for (int i = 0; i < len; ++i) data[i] = a.data[i];
        }
    
        int length() const { return len; }
    
        // Array element access - lvalue and rvalue
        virtual int & operator [] (int i) {
            static int bucket;
            return (i >= 0 && i < len) ? data[i] : bucket;
        }
        virtual int operator [] (int i) const {
            return (i >= 0 && i < len) ? data[i] : 0;
        }
    
        // Assignment (sizes need not match)
        Array & operator = (const Array & a) {
            delete [] data; data = new int[len = a.len];
            for (int i = 0; i < len; ++i) data[i] = a.data[i];
            return *this;
        }
    
        // Utility for printing
        virtual void print(ostream & o) {
            o << "[";
            for (int i = 0; i < length(); ++i)
                o << (i == 0 ? "" : " ") << data[i];
            o << "]";
        }
    
    private:
        int *data;   // The values in the array
        int len;     // The size of the array
    };
    
    inline
    ostream & operator << (ostream & o, const Array & a) {
        a.print(o);
        return o;
    }
    

  2. Given the declarations:
    int * (*x)(int *);   int i;
    
    1. What is the type of (*x)(&i) ?
    2. What is the type of *x ?

  3. What is the order in which constructors are called in a class inheritance hierarchy? What is the order in which the destructors are called?

  4. Why should a class that is going to be used as a base class define its destructor as virtual? What if the class does not need to define any code for a destructor?

  5. Describe the access control implemented by the keyword friend.

  6. If you do not define a copy constructor for a class that contains data fields of another class type, what happens when copy construction is needed? How about assignment? Same questions, but for one class deriving from another.

  7. Write a makefile that compiles a C++ program named hello from the source files hello1.c and hello2.c. Each source file includes a common header file named hello.h.

  8. Suppose we have this implementation of an Array of integers:
    class Array {
    public:
        Array(int size) : len(size) { data = new int[len]; }
        Array(const Array & a) : len(a.len) {
            data = new int[len];
            for (int i = 0; i < len; ++i) data[i] = a.data[i];
        }
        virtual ~Array() { delete [] data; }
    
        int length() const { return len; }
    
        // Array element access
        virtual int & operator [] (int i) {
            if (i < 0 || i >= len) throw Error("index out of bounds");
            return data[i];
        }
    
        // Assignment (sizes need not match)
        Array & operator = (const Array & a) {
            if (this == &a) return *this;
            delete [] data; data = new int[len = a.len];
            for (int i = 0; i < len; ++i) data[i] = a.data[i];
            return *this;
        }
    
        // Utility for printing
        virtual void print(ostream & o) const {
            o << "[";
            for (int i = 0; i < length(); ++i)
                o << (i == 0 ? "" : " ") << data[i];
            o << "]";
        }
    
        class Error {
        public:
            const char * const emessage;
            Error(const char * m = "") : emessage(m) { }
        };
    
    private:
        int *data;   // The values in the array
        int len;     // The size of the array
    };
    
    inline
    ostream & operator << (ostream & o, const Array & a) {
        a.print(o);
        return o;
    }
    
    And suppose you have the growable array derived from Array:
    class GrowableArray : public Array {
    public:
        GrowableArray(int size) : Array(size) { fill(); }
    
    private:
        // Grow the array and copy values
        void grow() {
            . . .
        }
    };
    
    You can assume that the method grow increases the array size by some amount. Show the code you would add to the class so that an out of range exception would not occur, but the array would grow to be the necessary size.