Egress

  1. What does the following C++ program output?
    #include <iostream>   //This file is main.C
    #include <cstdlib>
    using namespace std;
    
    int main()
    {
    	int i {10};
    	int& j {i};
    	++j;
    	cout << "i = " << i << "\n";
    
    	int n {20};
    	int& m {n};
    	++n;
    	cout << "m = " << m << "\n";
    
    	return EXIT_SUCCESS;
    }
    
  2. Why does operator<< have to be a friend function, rather than a member function?
  3. Why should operator== be a friend function, rather than a member function?
  4. Add to the following class obj the functions that would make it possible to execute all the statements in the main function. Hint: there would be nothing wrong in taking advantage of the existing operator+=.
    #ifndef OBJ_H   //This file is obj.h
    #define OBJ_H
    
    class obj {
    	int i;
    public:
    	obj(int init_i): i {init_i} {}
    
    	obj& operator+=(int n) {i += n; return *this;}
    };
    #endif
    
    #include <cstdlib>   //This file is main.C
    #inlcude "obj.h"
    
    int main()
    {
    	obj ob {10};
    	obj ob2 {ob + 2};  //Make it possible to apply a + to an obj.
    	obj ob3 {3 + ob};
    
    	return EXIT_SUCCESS;
    }
    
  5. Add to the following class obj the functions that would make it possible to execute all the statements in the main function. Hint: there would be nothing wrong in taking advantage of the existing operator+=.
    #ifndef OBJ_H   //This file is obj.h
    #define OBJ_H
    
    class obj {
    	int i;
    public:
    	obj(int init_i): i {init_i} {}
    
    	obj& operator+=(int n) {i += n; return *this;}
    };
    #endif
    
    #include <cstdlib>   //This file is main.C
    #inlcude "obj.h"
    
    int main()
    {
    	obj ob {10};
    	obj ob2 {++ob};  //Make it possible to apply a prefix  ++ to an obj.
    	obj ob3 {ob++};  //Make it possible to apply a postfix ++ to an obj.
    
    	return EXIT_SUCCESS;
    }
    
  6. Define the functions that would make it possible to execute all the statements in the following main function. Hint: there would be nothing wrong in taking advantage of the existing operator== and operator<.
    #ifndef OBJ_H   //This file is obj.h
    #define OBJ_H
    
    class obj {
    	int i;
    public:
    	obj(int init_i): i {init_i} {}
    
    	friend bool operator==(const obj& ob1, const obj& ob2) {
    		return ob1.i == ob2.i;
    	}
    
    	friend bool operator<(const obj& ob1, const obj& ob2) {
    		return ob1.i < ob2.i;
    	}
    };
    #endif
    
    #include <cstdlib>   //This file is main.C
    #inlcude "obj.h"
    
    int main()
    {
    	obj ob1 {10};
    	obj ob2 {20};
    
    	if (ob1 <= ob2) {
    		cout << "less than or equal to\n";
    	}
    
    	if (ob1 > ob2) {
    		cout << "greater than\n";
    	}
    
    	if (ob1 != ob2) {
    		cout << "not equal to\n";
    	}
    
    	if (ob1 >= ob2) {
    		cout << "greater than or equal to\n";
    	}
    
    	return EXIT_SUCCESS;
    }
    
  7. Define a pointer named p that would be capable of holding either the address of b or the address of d.
    #include <cstdlib>
    
    class base {
    	int i;
    public:
    	base(int init_i): i {init_i} {}
    };
    
    class derived: public base {
    	int j;
    public:
    	derived(int init_i, int init_j): base {init_i}, j {init_j} {}
    };
    
    int main()
    {
    	base b {10};
    	derived d {20, 30};
    
    	return EXIT_SUCCESS;
    }
    
  8. Will the following code call the version of the function f that is appropriate for each object? Specifically, will the following code call the base::f member function of the object b, and the derived::f member function of the object d? Why or why not?
    #ifndef BASE_H   //This file is base.h
    #define BASE_H
    #include <iostream>
    using namespace std;
    
    class base {
    public:
    	base() {}
    	virtual void f() const {cout << "basic version of f\n";}
    };
    
    #endif
    
    #ifndef DERIVED_H   //This file is derived.h
    #define DERIVED_H
    #include <iostream>
    #include "base.h"
    using namespace std;
    
    class derived: public base {
    public:
    	derived() {}
    	void f() {cout << "bigger and better version of f\n";}
    };
    
    #endif
    
    #include <cstdlib>   //This file is main.C
    using namespace std;
    
    int main()
    {
    	base b;
    	derived d;
    
    	base *a[] {     //a (very short) array of pointers
    		&b,
    		&d
    	};
    
    	for (auto p: a) {
    		p->f();   //Will this statement make the correct choices?
    	}
    
    	return EXIT_SUCCESS;
    }
    
  9. If we change the inheritance from public to private in the file derived.h, will the g member function still be able to call f? Will the main function still be able to call f?
    #ifndef BASE_H   //This file is base.h
    #define BASE_H
    
    class base {
    	int i;
    public:
    	base(int init_i): i {init_i} {}
    	void f() const;
    };
    
    #endif
    
    #ifndef DERIVED_H   //This file is derived.h
    #define DERIVED_H
    #include "base.h"
    
    class derived: public base {
    	int j;
    public:
    	derived(int init_i, int init_j): base {init_i}, j {init_j} {}
    	void g() const {f();}
    };
    
    #endif
    
    #include <iostream>   //This file is main.C
    #include <cstdlib>
    #include "derived.h"
    using namespace std;
    
    int main()
    {
    	derived d {10, 20};
    	d.f();
    	return EXIT_SUCCESS;
    }
    
  10. How many data members are inside of an object of class cowboybank?
    #ifndef COWBOY_H   //This file is cowboy.h
    #define COWBOY_H
    #include <iostream>
    using namespace std;
    
    class cowboy {
    	int i;
    	static int count;
    public:
    	cowboy(int init_i): i {init_i} {++count;}
    	cowboy(const cowboy& another): i {another.i} {}
    	~cowboy() {--count;}
    
    	void chew() const {cout << "Gimme a chaw 'a 'baccy.\n";}
    	void draw() const {cout << "Put 'em up, pardner!\n";}
    };
    
    #endif
    
    #ifndef BANK_H   //This file is bank.h
    #define BANK_H
    #include <iostream>
    using namespace std;
    
    class bank {
    	int j;
    public:
    	bank(int init_j): j {init_j} {}
    
    	void deposit() const {cout << "Please take a deposit slip.\n";}
    	void draw() const {cout << "Your account is overdrawn.\n";}
    };
    
    #endif
    
    #ifndef COWBOYBANK_H   //This file is cowboybank.h
    #define COWBOYBANK_H
    #include <iostream>
    #include "cowboy.h"
    #include "bank.h"
    using namespace std;
    
    class cowboybank: public cowboy, public bank {   //say "public" twice
    	int k;
    public:
    	cowboybank(int init_i, int init_j, int init_k)
    		: cowboy {init_i}, bank {init_j}, k {init_k} {}
    
    	void run() const {cout << "Time to clear out of town.\n";}
    };
    
    #endif
    
    #include <cstdlib>   //This file is main.C
    #include "cowboybank.h"
    
    int main()
    {
    	cowboybank cbb {10, 20, 30};
    
    	return EXIT_SUCCESS;
    }
    
  11. I want to look up the name of each city and find its population.
    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <vector>
    using namespace std;
    
    int main()
    {
    	vector<string> names {
    		"New York",
    		"Yonkers",
    		"Hastings",
    		"Dobbs Ferry",
    		"Irvington",
    		"Tarrytown"
    	};
    
    	vector<int> population {
    		8478072,   //New York
    		 211569,   //Yonkers
    		   9289,   //Hastings
    		  11541,   //Dobbs Ferry
    		   6653,   //Irvington
    		  11860    //Tarrytown
    	};
    
    	const size_t n {names.size()};
    
    	for (;;) {
    		cout << "Type a city (or control-d to quit): ";
    		string name;
    		getline(cin, name);
    		if (!cin) {
    			break;  //The user typed control-d
    		}
    
    		for (int i {0}; i < n; ++i) {
    			if (name == names[i]) {
    				cout << name << " " << population[i] << "\n";
    				break;
    			}
    		}
    	}
    
    	return EXIT_SUCCESS;
    }
    
    Instead of using two different flavors of class vector to hold these two columns of information, what would be a simpler way to do this? You don’t have to write the code; just describe the solution in words.
  12. Suppose that an object of a derived class needs a bigger and better operator<< than the one that outputs an object of a base class. (For example, maybe a derived object has two data members, while a base object has only one data member.) It would be nice if we could declare the operator<< to be a virtual function, but only member functions can be virtual. So how can we get the following two <<’s to do two different things?
    	base b {10};
    	derived d {20, 30};
    
    	cout << b << "\n";  //Output one data member.
    	cout << d << "\n";  //Output two data members.
    
    Don’t write the code; just describe the solution in words.
  13. How many copies of the grandparent object are in the following grandchild object?
    #ifndef GRANDPARENT_H   //This file is garndparent.h
    #define GRANDPARENT_H
    
    class grandparent {
    	int i;
    public:
    	grandparent(int init_i): i {init_i} {}
    };
    #endif
    
    #ifndef MOTHER_H   //This file is mother.h
    #define MOTHER_H
    #include "grandparent.h"
    
    class mother: public virtual grandparent {
    	int j;
    public:
    	mother(int init_i, int init_j): grandparent{init_i}, i {init_i} {}
    };
    #endif
    
    #ifndef FATHER_H   //This file is father.h
    #define FATHER_H
    #include "grandparent.h"
    
    class father: public virtual grandparent {
    	int k;
    public:
    	father(int init_i, int init_k): grandparent{init_i}, k {init_k} {}
    };
    #endif
    
    #ifndef GRANDCHILD_H   //This file is grandchild.h
    #define GRANDCHILD_H
    #include "mother.h"
    #include "father.h"
    
    class grandchild: public mother, public father {
    	int el;
    public:
    	grandchild(int init_i, int init_j, int init_k, int init_el):
    		grandparent {init_i},
    		mother {init_i, init_j},
    		father {init_i, init_k},
    		el {init_el} {}
    };
    #endif
    
    #include <cstdlib>   //This file is main.C
    #include "grandchild.h"
    
    int main()
    {
    	grandchild g {10, 20, 30, 40};
    
            return EXIT_SUCCESS;
    }