FreePOOMA Tutorials
A Quick Self-Test

Contents:
    Introduction
    Questions
        Object Creation
        Virtual Methods and Inheritance
        Trait Classes
        Values, References, and Constant References
    Answers
        Object Creation
        Virtual Methods and Inheritance
        Trait Classes
        Values, References, and Constant References

Introduction

The implementation of FreePOOMA uses many advanced or obscure features of the ANSI/ISO C++ standard. Its interface is less exacting, but programmers must still have a solid understanding of C++ to use it effectively. If you feel comfortable with the questions below, and their answers, you should have little or no difficulty using FreePOOMA. If, on the other hand, you find the questions and their answers difficult, you may wish to look at some of the books in the recommended reading before trying to use this library.

Questions

Object Creation

Assume that a default constructor, a copy constructor, and an overloaded assignment operator have been defined for the class Fred. How many times is each called when the following program is executed?
Fred red;

Fred func(
Fred cyan
){
Fred magenta;
magenta = cyan;
return magenta;
}

int main()
{
Fred green = red;
blue = func(green);
return 0;
}

Virtual Methods and Inheritance

What does the following program print out?

#include <iostream>
#include <iomanip>
using namespace std;

class A
{
public :
A() { cout << "A new" << endl; }
virtual void left() { cout << "A left" << endl; }
void right() { cout << "A right" << endl; }
};

class B : public A
{
public :
B() { cout << "B new" << endl; }
void left() { cout << "B left" << endl; }
void right() { cout << "B right" << endl; }
};

int main()
{
A a;
a.left();
a.right();
cout << endl;

B b;
b.left();
b.right();
cout << endl;

A * ap = &b;
ap->left();
ap->right();
cout << endl;

A * ap = (A*)&b;
ap->left();
ap->right();
cout << endl;

ap->A::left();
((A*)ap)->left();
((A*)ap)->right();

return 0;
}

Trait Classes

What does the following program print out?

class Blue
{
public :
enum { Val = 240; };
};

template<class T>
class Green
{
public :
const int Val = 88;
};

template<class T>
class Red
{
public :
enum { Val = T::Val/2; };
};

int main()
{
cout << Blue::Val << endl;
cout << Green<Blue>::Val << endl;
cout << Red<Blue>::Val << endl;
cout << Red<Green<Blue>>::Val << endl;
cout << Red<Green<Green<Blue>>>::Val << endl;
cout << Red<Red<Green<Blue>>>::Val << endl;
return 0;
}

Values, References, and Constant References

Which of the calls to value(), reference, and const_reference below produce errors during compilation?

void value(int x)
{}

void reference(int & x)
{}

void const_reference(const int & x)
{}

int main()
{
int x;
const int y = 2;

value(1);
value(x);
value(y);
value(x+1);

reference(1);
reference(x);
reference(y);
reference(x+1);

const_reference(1);
const_reference(x);
const_reference(y);
const_reference(x+1);

return 0;
}

Answers

Object Creation

The listing below shows where constructor calls and assignments occur:

Fred red;                               // default constructor

Fred func(
Fred cyan // copy constructor
// (pass by value)
){
Fred magenta; // default constructor
magenta = cyan; // assignment operator
return magenta; // copy constructor
// (magenta is copied into
// a nameless temporary to
// be returned)
}

int main()
{
Fred green = red; // copy constructor
blue = func(green); // copy constructor twice
// ('green' is copied into
// 'cyan' during call, and
// temporary return value
// is copied into 'blue' on
// exit)
return 0;
}

Virtual Methods and Inheritance

The program prints the following:

A new                                   // A::A()
A left // A::left()
A right // A::right()

A new // B::B() invokes A::A()
B new // body of B::B()
B left // B::left()
B right // B::right()

B left // left() is virtual
A right // right() is not virtual

B left // cast on right irrelevant
A right // right() is not virtual

A left // exact method named
B left // cast on left irrelevant
A right // right() is not virtual

Trait Classes

The key here is that Green always defines its own Val, while Red defines its Val in terms of its argument class's Val. The answer is therefore:

int main()
{
cout << Blue::Val << endl; // 240
cout << Green<Blue>::Val << endl; // 88
cout << Red<Blue>::Val << endl; // 120
cout << Red<Green<Blue>>::Val << endl; // 44
cout << Red<Green<Green<Blue>>>::Val << endl; // 44
cout << Red<Red<Green<Blue>>>::Val << endl; // 22
return 0;
}

Values, References, and Constant References

The only outright errors occur when a constant value (such as a literal or the result of an arithmetic expression) is passed where a non-constant reference parameter is expected. There is also a warning when x is used before being assigned a value:

int main()
{
int x;
const int y = 2;

value(1);
value(x); // Warning, value used before set.
value(y);
value(x+1);

reference(1); // Error. Non-const reference to const.
reference(x);
reference(y); // Error. Non-const reference to const.
reference(x+1); // Error. Non-const reference to const.

const_reference(1);
const_reference(x);
const_reference(y);
const_reference(x+1);

return 0;
}


Copyright © Los Alamos National Laboratory 1998-2000