Study Guide 10: Multi-Class Programs


    The connector between Alpha and Gamma has a solid diamond attached to Alpha. The connector between Beta and Delta has an outlined diamond attached to Beta. The connector between Gamma and Delta has an outlined, three-sided arrow head attached to Gamma. The connector between Gamma and Zeta is an undecorated line. Delta and Epsilon are connected by a dashed line with an open arrowhead attached to Epsilon.

    The following questions refer to the UML class diagram at the right.

  1. What is the relationship between Alpha and Gamma?
    1. Inheritance (which is the superclass and which is the subclass?)
    2. Composition (which is the whole class and which is the part?)
    3. Aggregation (which is the whole class and which is the part?)
    4. Association (what roles do the related classes play?)
    5. Dependence (which is the dependent/client class and which is the independent/supplier?)
  2. What is the relationship between Beta and Delta?
    1. Inheritance (which is the superclass and which is the subclass?)
    2. Composition (which is the whole class and which is the part?)
    3. Aggregation (which is the whole class and which is the part?)
    4. Association (what roles do the related classes play?)
    5. Dependence (which is the dependent/client class and which is the independent/supplier?)
  3. What is the relationship between Delta and Gamma?
    1. Inheritance (which is the superclass and which is the subclass?)
    2. Composition (which is the whole class and which is the part?)
    3. Aggregation (which is the whole class and which is the part?)
    4. Association (what roles do the related classes play?)
    5. Dependence (which is the dependent/client class and which is the independent/supplier?)
  4. What is the relationship between Zeta and Gamma?
    1. Inheritance (which is the superclass and which is the subclass?)
    2. Composition (which is the whole class and which is the part?)
    3. Aggregation (which is the whole class and which is the part?)
    4. Association (what roles do the related classes play?)
    5. Dependence (which is the dependent/client class and which is the independent/supplier?)
  5. What is the relationship between Delta and Epsilon?
    1. Inheritance (which is the superclass and which is the subclass?)
    2. Composition (which is the whole class and which is the part?)
    3. Aggregation (which is the whole class and which is the part?)
    4. Association (what roles do the related classes play?)
    5. Dependence (which is the dependent/client class and which is the independent/supplier?)

  6. Identify the class relationship represented by each code fragment.
  7. class Ceres
    {
        ...
    };
    
    class Vesta
    {
        private:
            Ceres* c;
    };
  8.  
  9. class Pallas
    {
        ...
    };
    
    class Hygiea
    {
        private:
            Pallas p;
    };
  10. class Doris
    {
        ...
    };
    
    class Cybele
    {
        public:
            void function()
            {
                Doris d;
                ...
            }
    };
  11.  
  12. class Hektor;
    
    class Camilla
    {
        private:
            Hektor* h;
    };
    
    class Hektor
    {
        private:
            Camilla* c;
    };
  13. class Psyche
    {
        ...
    };
    
    class Fortuna
    {
        public:
            void function(Psyche p);
    };
  14.  
  15. class Europa
    {
        ...
    };
    
    class Juno : public Europa
    {
        ...
    };

  16. Match each statement with the correct term: overloaded or overridden functions.
  17. Two functions with the same name, same return type, and parameter list.
  18. Two functions with the same name, but they must have different parameters; the return types may be the same or different.
  19. Two functions with the same name defined in the same class or scope.
  20. Two functions with the same name defined in classes related by inheritance.

  21. If Bar is a class that defines a member function named function and a program contains the definition Bar b;, which of the following is an example of "sending a message" to object b?
    1. function(b);
    2. b.function();
    3. b;
    4. function();
    5. None of the above.
  22. Examine the following code fragments:
    class foo
    {
    	public:
    		foo();
    };
    
    class bar : public foo
    {
    	public:
    		________________
    };
    Which of the following are valid bar constructors (including the initializer lists)? (Mark all that are valid.)
    1. bar();
    2. bar(int a) : foo();
    3. bar(int a, char b) : foo(a);
    4. bar(int a, char b) : foo(a, b);
  23. Examine the following code fragments:
    class foo
    {
    	public:
    		foo(int x);
    };
    
    class bar : public foo
    {
    	public:
    		________________
    };
    Which of the following are valid bar constructors (including the initializer lists)? (Mark all that are valid.)
    1. bar() : foo(10);
    2. bar(int a) : foo(a);
    3. bar(int a, char b) : foo(a);
    4. bar(int a, char b) : foo(a, b);
  24. Examine the following code fragments:
    class foo
    {
    	public:
    		foo(int x, int y);
    };
    
    class bar : public foo
    {
    	public:
    
    };
    Which of the following are valid bar constructors (including the initializer lists)? (Mark all that are valid.)
    1. bar() : foo(10);
    2. bar(int a) : foo(a);
    3. bar(int a, int b) : foo(a);
    4. bar(int a, int b) : foo(a, b);
  25. What happens here runs?
    class foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    		void function2() { /* do stuff here */ }
    };
    
    class bar : public foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    };
    
    int main()
    {
    	bar b;
    	b.function1();
    	return 0;
    }
    
    1. Calls function1 from the bar class.
    2. Calls function1 from the foo class.
    3. Will not compile because function1 is defined multiple times.
    4. Will not compile because the scope resolution operator must be used to distinguish between the function1 defined in foo and the function1 defined in bar.
  26. What happens here runs?
    class foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    		void function2() { /* do stuff here */ }
    };
    
    class bar : public foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    };
    
    int main()
    {
    	bar b;
    	b.function2();
    	return 0;
    }
    1. Calls function2 from the bar class.
    2. Calls function2 from the foo class.
    3. Will not compile because function2 is not defined in class bar.
    4. Will not compile because the scope resolution operator must be used to distinguish between the function1 defined in foo and the function1 defined in bar.
  27. What happens here (choose the most complete description - caution, very tricky)?
    class foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    		void function2() { /* do stuff here */ }
    };
    
    class bar : public foo
    {
    	public:
    		void function1() { function1(); }
    };
    
    int main()
    {
    	bar b;
    	b.function1();
    	return 0;
    }
    1. Calls function1 from the bar class.
    2. Calls function1 from the foo class.
    3. Calls function1 from the bar class but results in run-away recursion, which crashes the program.
    4. Will not compile because function1 in bar is ambiguous.
    5. Will not compile because function2 is not matched in bar.
  28. What happens here?
    class foo
    {
    	public:
    		void function1() { /* do stuff here */ }
    		void function2() { /* do stuff here */ }
    };
    
    class bar : public foo
    {
    	public:
    		void function1() { foo::function1(); }
    };
    
    int main()
    {
    	bar b;
    	b.function1();
    	return 0;
    }
    1. Calls function1 from the bar class.
    2. Calls function1 from the foo class.
    3. Calls function1 from the bar class but results in run-away recursion, which crashes the program.
    4. Calls function1 from the bar class, which calls function1 from the foo class.
    5. Will not compile because function1 in bar is ambiguous.
    6. Will not compile because function2 is not matched in bar.
  29. What happens here (assume appropriate header files are included - also tricky)?
    class foo
    {
    	private:
    		int	counter;
    	public:
    				foo(int c) : counter(c){}
    };
    
    class bar : public foo
    {
    	public:
    				bar(int c) : foo(c){}
    		void	function() { cout << counter << endl; }
    };
    
    int main()
    {
    	bar b(10);
    	b.function();
    	return 0;
    }
    1. Prints 10.
    2. Compiles but will crash on the statement cout << counter << endl;.
    3. Compiles but will crash on the statement b.function();.
    4. Does not compile.
  30. What happens here?
    class foo
    {
    	private:
    		int		my_data;
    
    	public:
    				foo(int d) : my_data(d) {}
    		void	print() { cout << my_data << endl; }
    };
    
    class bar
    {
    	private:
    		int		my_data;
    
    	public:
    				bar(int d) : my_data(d) {}
    		void	print() { cout << my_data << endl; }
    };
    
    int main( )
    {
    	foo	obj1(5);
    	bar	obj2(10);
    
    	obj2.print();
    
    	return 0;
    }
    1. Does not compile.
    2. Does not run.
    3. Prints 5.
    4. Prints 10.

  31. Use the UML class diagram to answer the following questions, which are about the initializer list needed to complete the class B constructor:

    B(int w, int x, int y, int z) : ______________________; Three classes connected by inheritance and composition:
A
--

--
+ A(w : int, x : int)

B
--

--
+ B(w : int, x :int, y : int, z : int)

C
--

--
+ C(y :int, z : int)

B is a subclass of A; B is a whole and C is a part.
  32. When forming the initializer list for class B,
    1. the code to initialize inheritance must appear first in the list.
    2. the code to initialize composition must appear first in the list.
    3. the order that the relationships are initialized does not matter.
  33. Choose the best code to initialize the inheritance relationship.
    1. A(w, x)
    2. A(w), A(x)
    3. inheritance(w, x)
    4. super(w, x)
  34. Assume that composition is implemented with a member variable named my_C. Choose the best code to initialize the composition relationship.
    1. C(y, z)
    2. C(a, b)
    3. C(y), C(z)
    4. my_C(y, z)
    5. my_C(y), my_C(z)

  35. The following code fragment denotes a composition relationship between classes Bar and Foo:
    class Bar
    {
    	private:
    		int	x;
    		char	y;
    
    	public:
    		Bar(int a, char b) : x(a), y(b) {}
    };
    
    class Foo
    {
    	private:
    		string	i;
    		Bar		my_bar;
    
    	public:
    		Foo(int a, char b, string c) : __________, i(c) {}
    };
    Fill in the blank to complete the Foo constructor to initialize the member variables in the Bar superclass.
  36. The following code fragment denotes a composition relationship between classes Bar and Foo:
    class Bar
    {
    	private:
    		. . . .
    
    	public:
    		void display()
    		{
    			. . . .
    		}
    };
    
    class Foo
    {
    	private:
    		int	i;
    		Bar	my_bar;
    
    	public:
    		void display()
    		{
    			__________________;
    			cout << i << endl;
    		}
    };
    Fill in the blank to complete the Foo display function to print the member variables in my_bar.
  37. The following code fragment denotes an aggregation relationship between classes Bar and Foo:
    class Bar
    {
    	private:
    		. . . .
    
    	public:
    		void display()
    		{
    			. . . .
    		}
    };
    
    class Foo
    {
    	private:
    		int	i;
    		Bar*	my_bar;
    
    	public:
    		void display()
    		{
    			if (my_bar != nullptr)
    				_________________ ;
    			cout << i << endl;
    		}
    };
    Fill in the blank to complete the Foo display function to print the member variables in my_bar.
  38. Examine the following two classes and determine which, if any, require an overridden copy constructor.
    class foo
    {
    	private:
    		string	name;
    		double	salary;
    };
    
    class bar
    {
    	private:
    		char*	name;
    		double	salary;
    };
    1. class foo
    2. class bar
    3. both classes
    4. neither class
  39. Write the needed copy constructor(s) for the classes in the previous question, or explain why neither class needs a copy constructor.
  40. The following code fragment denotes an inheritance relation between classes Bar and Foo (the highlighted characters are labels and not part of the code):
    class Bar
    {
    	private:
    		int		count;
    		double	balance;
    
    	public:
    		Bar(int a_count, double a_balance):(a) ________ {}
    
    		void display()
    		{
    			cout << count << " " << balance << endl;
    		}
    };
    
    class Foo : public Bar
    {
    	private:
    		string	name;
    
    	public:
    		Foo(string a_name, int count, double balance):
    			(b) __________________________________________
    
    		void display()
    		{
    			(c) _______________________;	// display inherited Bar
    			out << name << endl;
    		}
    };
    Fill in the blanks to complete the program.
  41. The following code fragment denotes a composition relationship between classes Bar and Foo (the highlighted characters are labels and not part of the code):
    class Bar
    {
    	private:
    		int	count;
    		double	balance;
    
    	public:
    		Bar(int c, double b) : (a) _____________________;
    
    		void display()
    		{
    			cout << count << " " << balance << endl;
    		}
    };
    
    class Foo
    {
    	private:
    		string	name;
    		Bar	my_bar;
    
    	public:
    		Foo(string n, int c, double b) : (b) ______________________;
    
    		void display()
    		{
    			(c) ___________________________;
    			cout << count << endl;
    		}
    };
    Fill in the blank to complete the program.
    1. Complete the Bar initializer list
    2. Complete the Foo initializer list
    3. Display my_bar
  42. The following code fragment denotes an aggregation relationship between classes Bar and Foo (the highlighted characters are labels and not part of the code):
    class Bar
    {
    	private:
    		int		count;
    		double	balance;
    
    	public:
    		Bar(int c, double b) : (a) _____________________;
    
    		void display()
    		{
    			cout << count << " " << balance << endl;
    		}
    };
    
    class Foo
    {
    	private:
    		string	name;
    		Bar*	my_bar = nullptr;
    
    	public:
    		Foo(string n) : (b) ______________________;
    
    		~Foo() { (c) _________________________________; }
    
    		void set_bar(int c, double b)
    		{
    			(d) _____________________________;
    			(e) _____________________________;
    		}
    
    		void display()
    		{
    			(f) ___________________________;
    			cout << count << endl;
    		}
    };
    Fill in the blanks to complete the program.
    1. Complete the Bar initializer list
    2. Complete the Foo initializer list
    3. Safely complete the destructor
    4. Prevent a memory leak
    5. Build a new aggregation relationship
    6. Display my_bar if it's not null
  43. Describe one inheritance characteristic setting it apart from the other UML class relationships.
  44. Describe one association characteristic setting it apart from the other UML class relationships.
  45. Composition and aggregation are the same in many ways. Describe their characteristics that differentiates between them.