Programming in C and C++ (2020/21)
Supervision 2

1

If a function f has a static instance of a class as a local variable, when might the class constructor be called?

2

Write a class Matrix which allows a programmer to define 2 × 2 matrices. Overload the common operators (e.g. +, -, *, and /). Can you easily extend your design to matrices of arbitrary size?

3

Write a class Vector which allows a programmer to define a vector of length two. Modify your Matrix and Vector classes so that they interoperate correctly (e.g. v2 = m*v1 should work as expected).

4

Using meta programming, write a templated class Prime, which evaluates whether a literal integer constant (e.g. 7) is prime or not at compile time.

5

How can you be sure that your implementation of class Prime has been evaluated at compile time?

6

Write an implementation of a class LinkList which stores zero or more positive integers internally as a linked list on the heap. The class should provide appropriate constructors and destructors and a method pop() to remove items from the head of the list. The method pop() should return -1 if there are no remaining items. Your implementation should override the copy constructor and assignment operator to copy the linked-list structure between class instances. You might like to test your implementation with the following:

int main() {
    int test[] = {1,2,3,4,5};
    LinkList l1(test+1,4), l2(test,5);
    LinkList l3 = l2, l4;
    l4 = l1;
    printf("%d %d %d\n", l1.pop(), l3.pop(), l4.pop());
    return 0;
}

Hint: heap allocation and deallocation should occur exactly once!

7

Why should destructors in an abstract class almost always be declared virtual?

8

Provide an implementation for:

    Stack(const Stack& s);
    Stack& operator=(const Stack& s);

as declared in the slides for lecture 7.

9

Provide an implementation for:

    template<class T> T Stack<T>::pop();
    template<class T> Stack<T>::~Stack();

as declared in the slides for lecture 7.

10

A hardware engineer stores a FIFO queue of bits in an int on a platform with
32-bit ints and 8-bit chars using the following C++ class:

class BitQueue {
    int valid_bits; // the number of valid bits held in queue
    int queue;      // least significant bit is most recent bit added
public:
    BitQueue(): valid_bits(0), queue(0) {}
    void push(int val, int bsize);
    int pop(int bsize);
    int size();
};
  1. Write an implementation of BitQueue::size which should return the number
    of bits currently held in queue.

  2. Write an implementation of BitQueue::push which places the bsize least
    significant bits from val onto queue and updates valid_bits. An
    exception should be thrown in cases where data would otherwise be lost.

  3. Write an implementation of BitQueue::pop, which takes bsize bits from
    queue, provides them as the bsize least significant bits in the return
    value, and updates valid_bits. An exception should be thrown when any
    requested data is unavailable.

  4. The hardware engineer has built a communication device together with a C++
    library function send to transmit data with the following declaration:
    void send(char);
    Use the BitQueue class to write a C++ definition for:

     void sendmsg(const char* msg);
            

    Each of the characters in msg should be encoded, in index order, using the
    following binary codes: 'a'=0, 'b'=10, 'c'=1100, and 'd'=1101. All
    other characters should be ignored. Successive binary codes should be
    bit-packed together and the code 111 should be used to denote the end of
    the message. Chunks of 8-bits should be sent using the send function and any
    remaining bits at the end of a message should be padded with zeros. For
    example, executing

     sendmsg("abcd");
            

    should call the send function twice, with the binary values 01011001
    followed by 10111100.