# midterm example discussion ## Q2: explain all compile-time errors and fix them **The incorrect codes** / The correct codes ```cpp= #include <iostream> class Date { public: int Date(int y, int m = 0, int d); // v -1 Date(Date src) { // -1 setDate(src.year, src.month, src.day); counter++; } void ~Date(); // v void setDate(int y, int m, int d) const { // v year = y; month = m; day = d; } void getDate(int &y, int &m, const int &d) { // v y = year; m = month; d = day; // v } static int getCount() { print(*this); // v -1 return counter; } friend print(const Date &date); // v private: int ndays; static int counter = 0; // v int year; int month; int day; }; void print(const Date &d) { // v cout << d->year << d->month << d->day; // v } int print(const Date &d, int cnt = 0) { // v cout << d.year << d.month << d.day << cnt; // -1 return getCount(); // v } int main() { int y = 2019, m = 11, d = 22; Date day1(2019, 11, 11); Date *day2 = new Date(y, m, d); Date days[10]; std::cout << day1.counter; // -1 day2->setDate(&y, &m, &d); // -1 print(days[1]); delete [] days; } // guessing (v if true else x) /* L4: constructor should have no returning type. L4: constructor is not implemented yet. Date(int y, int m = 0, int d): year(y), month(m), day(d) {} L4: constructor should have no returning type. L9: destructor is not implemented yet. ~Date(){} L10: modifier method should not be marked as const (it implies read-only method) void setDate(int y, int m, int d) { L16: the const paramter d is not modifiable. void getDate(int &y, int &m, int &d) { y = year; m = month; d = day; } L19: *this is unavailable, the function is static. static int getCount() { return counter; } L??: cout is not defined. cout --> std::cout L22: friend function print has no returning type L30: unambiguity L33: unambiguity friend void print(const Date &date); friend int print(const Date &date, int cnt); // ... void print(const Date &d) { int print(const Date &d, int cnt) { L25: non const static data member cannot initialize in class. static inline int counter = 0; L31: const Date& is not deferenceable (non-pointer type). cout << d.year << d.month << d.day; L35: getCount is not defined return Date::getCount(); L42: no member names counter in day1. (X) cout << Date::counter; */ // missing (-1) /* L5: invalid constructor; you probably meant 'Date (const Date&)' L4: default argument missing for parameter 3 of 'Date::Date(int, int, int)' Date(int y, int m = 0, int d = 0); L19: 'print' was not declared in this scope friend print(const Date &date); // v static int getCount() { print(*this); // v -1 return counter; } L34: error: 'int Date::year' is private within this context L42: counter is private member static int counter = 0; private: L43: invalid conversion from 'int*' to 'int' day2->setDate(y, m, d); */ ``` The incorrect codes / **The correct codes** ```cpp= #include <iostream> class Date { public: Date(){} // Date(int y, int m, int d): year(y), month(m), day(d) {} // Date(const Date &src) { // setDate(src.year, src.month, src.day); counter++; } ~Date(){} // void setDate(int y, int m, int d) { // year = y; month = m; day = d; } void getDate(int &y, int &m, int &d) { // y = year; m = month; d = day; } friend void print(const Date &date); // friend int print(const Date &date, int cnt); // static int getCount() { // return counter; } static inline int counter = 0; // private: int ndays; int year; int month; int day; }; void print(const Date &d) { std::cout << d.year << d.month << d.day; // } int print(const Date &d, int cnt) { // std::cout << d.year << d.month << d.day << cnt; return Date::getCount(); // } int main() { int y = 2019, m = 11, d = 22; Date day1(2019, 11, 11); Date *day2 = new Date(y, m, d); Date days[10]; std::cout << day1.counter; day2->setDate(y, m, d); // print(days[1]); delete [] days; } ``` ## Q3: callers (1-16) and callees (A-H) callees (A-H) ```cpp= A: TimeOfDate(int h=0, int m=0); B: TimeOfDate(float i); C: TimeOfDate(char *str); D: TimeOfDate(const TimeOfDate &src); E: ~TimeOfDate(); F: operator int() const; G: operator char *() const; H: TimeOfDate & operator=(const TimeOfDate &src); ``` callers (1-16) ```cpp= TimeOfDate t1; static TimeOfDate t2(“12:30”); TimeOfDate &foo(TimeOfDate t3) { TimeOfDate t4=t3; TimeOfDate *t5 = new TimeOfDate[2]; return t4; } int main() { TimeOfDate *t6 = new TimeOfDate(3.5); TimeOfDate t7(12,30); foo(*t6) = t2; delete t6; int i = t2; cout << (char *)t1 << i; return 0; } ``` guessing answer ```= A C D D A E B A H E F G E ``` The memory management problems ```= Line 3, 6: returning local reference Line 5: not free'd ``` ## Q4: Common Compile-Time Errors a. guessing answer ```cpp= B::B(int v): a(v) {} ``` b. ```cpp= class B, C; class A { public: A(int u) {x=u;} int f(); private: friend B; int g() const; int x; }; class B { public: B(int v=0); int f(); private: A a; }; class C { public: static int g(); B *operator->(); private: static int x; int y; B *pb; }; B b; C c; ``` guessing answer ```cpp= int x1 = c.x; // C::x is private member, it should be public int x2 = b.f(); // legal, it returns an int type directly int x3 = C::g(); // legal, it returns an int type by calling the static method int y = b.a.f(); // a is a private member of b, it should be public int z = c->f(); // legal, it returns an int type by calling B::f() int A::g() const { return f(); } // A::f() is non-const method, it cannot be called by const method A::g() void B::f() { a.x = 1; } // legal, B which is a friend of A assigns 1 to the private member x int C::g() { return y = x; } // C::g() is a static method of A, which has no implicit this pointer holding y ``` ## Q5: Operator Overloading ```cpp= #include <iostream> using namespace std; // don't forget this line class Nint { public: Nint(int v=0) { x=v; } Nint& operator=(int i) { x=i; return(*this);} Nint operator+(const Nint &o) { return( x + o.x); } friend ostream &operator<<( ostream &, const Nint& ); private: int x; }; ostream &operator<<(ostream &o, const Nint &v) { o << v.x; return(o); } int main(void) { Nint a=3,b=7,c,d,e; cout << "A is " << a << endl; cout << "B is " << b << endl; c = a + b; cout << "C is " << c << endl; d = a + 7 + c; cout << "D is " << d << endl; cout << "E is " << e << endl; } ``` guessing answer a. ```= A is 3 B is 7 C is 10 D is 20 E is 0 ``` b. if the returning type is ostream, will it compile? ``` In Line 15, the copy constructor of ostream is called, which is deleted. It won't compile. ``` c. If you don’t have the global operator overloading of operator<< (lines 11-14), is it possible to add another operator overloading of Nint to make the program compile? ```cpp= It is impossible to add only one operator to compile, the crucial function is: operator<<(ostream& o, Type var). The following casting operator is used for operator<<(ostream& o, const char* var); Nint::operator const char*() const { return make_unique<string>(to_string(x))->c_str(); } However, the implicit casting will cause the conflicts between operator+(const char*, int) and Nint::operator+(const Nint&). So it needs two operators to make it compile: Nint Nint::operator+(int i) { return(x + i); } Nint::operator const char*() const { return make_unique<string>(to_string(x))->c_str(); } ``` ### Q6: OOD ```cpp= #include <cmath> class Pokemon { int attack; int defense; int stamina; float CPM; public: Pokemon(int attack, int defense, int stamina, float CPM): attack(attack), defense(defense), stamina(stamina), CPM(CPM) {} float CP() const { return (attack * pow(defense, 0.5) * pow(stamina, 0.5) * pow(CPM, 2)) / 10; } bool operator==(const Pokemon &_) const { return attack == _.attack && defense == _.defense && stamina == _.stamina && CPM == _.CPM; } bool operator!=(const Pokemon &_) const { return !(*this == _); } bool operator>(const Pokemon &_) const { return CP() > _.CP(); } bool operator<(const Pokemon &_) const { return CP() < _.CP(); } }; ```