#include <iostream> #include <string> using namespace std; // Declare the MyObject class class MyObject { public: static int numObjs; MyObject(); // default constructor MyObject(string n); // constructor with name parameter MyObject(const MyObject& rhs); // copy constructor ~MyObject(); // destructor string getName() const; void setName(const string& newName); friend ostream& operator<<(ostream& output, const MyObject& obj); private: string name; int id; }; // Define the member functions we declared above // Remember: member functions are defined as Class::method() // Constructors and destructors - no return types MyObject::MyObject() { // Important: notice how we don't define 'name' or 'id' here // Instead, we're setting the variables that we declared in MyObject name = "--default--"; id = ++numObjs; cout << "MyObject Default constructor: " << *this << endl; } MyObject::MyObject(string n) { name = n; id = ++numObjs; cout << "MyObject Parameter constructor: " << *this << endl; } MyObject::MyObject(const MyObject& rhs) { name = rhs.name; id = ++numObjs; cout << "MyObject Copy constructor: " << *this << endl; } MyObject::~MyObject() { cout << "MyObject Destructor: " << *this << endl; } // Regular methods, with return types string MyObject::getName() const { return name; } void MyObject::setName(const string& newName) { name = newName; } // Let cout know how to print MyObjects ostream& operator<<(ostream& output, const MyObject& obj) { // output in format: ("object name", id) return output << "(\"" << obj.name << "\", " << obj.id << ")"; } // Prototypes for non-member functions we define later on // These are *non-member* functions because we didn't declare them as part of the MyObject class MyObject getMaxMyObj(const MyObject o1, const MyObject o2); int cmpMyObj(const MyObject o1, const MyObject o2); void swapMyObj(MyObject& o1, MyObject& o2); // Static variables int MyObject::numObjs = 0; // static member for all objects in class static MyObject staticObj("I'm static, outside of main"); int main () { cout << "--PART 1: Start of main--" << endl; cout << "--Defining o1, o2(\"Bob\")--" << endl; MyObject o1, o2("Bob"); cout << "--Defining o3(o2)--" << endl; MyObject o3(o2); cout << "--Defining array of 3 objects--" << endl; MyObject array[3]; cout << endl; cout << "--PART 2: call function using call-by-value, return int--" << endl; cmpMyObj(o1, o3); cout << "--call function using call-by-value, return MyObject--" << endl; getMaxMyObj(o1, o3); cout << endl; cout << "--PART 3: o1: " << o1 << endl; { cout << " --entering new block, define new o1(Sally)--" << endl; MyObject o1("Sally"); o1.setName("Sally"); cout << " o1: " << o1 << "\to2: " << o2 << endl; cout << " --call swap function using call-by-reference--" << endl; swapMyObj(o1, o2); cout << " --were their values swapped?--" << endl; cout << " o1: " << o1 << "\to2: " << o2 << endl; cout << " --leaving new block--" << endl; } cout << "o1: " << o1 << endl; cout << endl; cout << "--PART 4: Define reference var: { MyObject& oref=o1; } --" << endl; { MyObject& oref=o1; } cout << "-- was anything constructed/destructed?--" << endl; cout << endl; cout << "--PART 5: new and delete--" << endl; cout << "--use new to create one object, then array of 2 objects--" << endl; MyObject *op1 = new MyObject, *op2 = new MyObject[2]; cout << "--use delete to remove that one object--" << endl; delete op1; cout << "--use delete [] to remove that array of 2 objects --" << endl; delete[] op2; cout << endl; cout << "--LAST PART: End of main--" << endl; return 0; } // Define the functions we declared earlier int cmpMyObj(const MyObject o1, const MyObject o2) { string name1 = o1.getName(), name2 = o2.getName(); if (name1 == name2) { return 0; } else if (name1 < name2) { return -1; } else { return 1; } } MyObject getMaxMyObj(const MyObject o1, const MyObject o2) { string name1 = o1.getName(), name2 = o2.getName(); if (name1 >= name2) { return o1; } else { return o2; } } void swapMyObj(MyObject& o1, MyObject& o2) { MyObject tmp(o1); o1.setName(o2.getName()); o2.setName(tmp.getName()); }