OOP Midterm solutions === Contributed by < `25077667` > Date: 2020/10/29 Creative Commons [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/tw/) * What are the three main characteristics of oop, in English? * Encapsulation * Inheritance * Polymorphism --- * Given the following C++ program, which of the declarations on lines 3 and 4 is an initialization and which is an assignment? ```cpp= int main() { int a = 1; int b = a; } ``` Both are initialization. --- * What would be the output of the following C++ program? What are the mechanisms used by C++ to call each of the three functions f, g, and h? ```cpp= #include <iostream> using std::cout; using std::endl; void f(int x, int y) { int t = x; x = y; y = t; } void g(int *x, int *y) { int t = *x; *x = *y; *y = t; } void h(int& x, int& y) { int t = x; x = y; y = t; } int main() { int a = 1, b = 2; f(a, b); cout << a << ", " << b << endl; g(&a, &b); cout << a << ", " << b << endl; h(a, b); cout << a << ", " << b << endl; return 0; } ``` Output: > 1, 2 > 2, 1 > 1, 2 Mechanisms: ```void f(int x, int y)``` > pass by value of a variable ```void g(int *x, int *y)``` > pass by value of a pointer ```void h(int &x, int &y)``` > pass by reference --- * What's output? ```c= #include <stdio.h> int f(int i) { static int v = 1; int t = v; v += i; return t; } int main() { int i; for (i = 1; i <= 8; i <<= 1) printf("%d\n", f(i)); return 0; } ``` > 1 > 2 > 4 > 8 --- * Use typedef to declare “foo” as an array of 3 pointers to functions taking as input an integer and returning as output an integer in a single declaration in C++. ```cpp typedef int (*foo[3])(int); ``` or ```cpp using foo = int (*[3])(int); ``` --- * Define an integer variable “`a`” in C++ so that it can only be seen in the file at which it is defined. ```cpp static int a; ``` or ```cpp namespace { int a; } ``` --- * Define in a single declaration in C++ a pointer to integer “p” so that p[1] is an alias of a[0], p[2] is an alias of a[1], and so on, all the way up to p[128] is an alias of a[127] for the integer array “int a[128];” defined in C++. ```cpp auto p = a - 1; ``` or ```c int *p = a - 1; ``` --- * What's output? ```c= #include <stdio.h> #define SQUARE(x) x*x int main() { printf("%d\n", SQUARE(1+2*3)*SQUARE(3+4*5)); return 0; } ``` > 105 --- * What is (most) wrong with the C++ function `f` below? ```cpp= static int i = -1; int *f() { int a[10]; for (i = 0; i < 10; i++) { a[i] = i; } return a; } ``` > Return a local variable of an array (dangling pointer). It would cause a segfault as a signal `SIGSEGV` while accessing the value of the returned pointer. --- * What is (most) wrong with the C++ function `g` below? ```cpp= #include <stdlib.h> #include <string.h> char *g() { char *d = (char *) malloc(128); char *s = "Now is the time..."; strcpy(d, s); free(s); return d; } ``` > `free` the [.rodata](https://pic1.xuehuaimg.com/proxy/csdn/https://img-blog.csdnimg.cn/20200519103314194.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FjZGVmZ2hi,size_16,color_FFFFFF,t_70). It will cause a `SIGABRT` in runtime immediately. --- * What's output? ```c= #include <stdio.h> int main() { int i = 55555; printf("%08X\n", * (unsigned int *) &i); i = -i; printf("%08X\n", * (unsigned int *) &i); return 0; } ``` The output > 0000D903 > FFFF26FD Explain: > Please read the format string rules. [Format string wiki](https://zh.wikipedia.org/wiki/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2) --- * What's output? ```c= #include <stdio.h> int main() { float i = 55555; printf("%08X\n", * (unsigned int *) &i); i = -i; printf("%08X\n", * (unsigned int *) &i); return 0; } ``` The output > 47590300 > C7590300 --- * What's output? ```cpp= #include <iostream> using std::cout; using std::endl; int main() { int a = 100; cout << ++a-- << endl; return 0; } ``` The output ``` error: lvalue required as increment operand 7 | cout << ++a-- << endl; | ^~ ``` --- * What's output? ```cpp= #include <iostream> using std::cout; using std::endl; int main() { int a[10][20][30][40][50]; cout << a[1]-a[6] << endl; cout << a[1][1]-a[6][6] << endl; return 0; } ``` The output > -100 > -3150 For the first line: > 20 pointers for each `a[i]`, a[1] to a[6] crossing 5 `a[i]`, 5 * 20 = 100, but a[1] is lower than a[6] in memory space, hence a[1]-a[6] is negative. For the second line: ![](https://i.imgur.com/c9CthD7.png) > Form the a[1][1] black dot to a[6][6] black dot. > each box has 30 elements. $(19+20 \cdot 4+6) \cdot 30 = 3150$ --- * What's output ```cpp= #include <iostream> using std::cout; using std::endl; #define MIN(a,b) (((a) < (b))? (a) : (b)) int main() { int x = 7, y = 8; int m = MIN(x++, y++); int n = MIN(++x, ++y); cout << m << " " << n << endl; return 0; } ``` The output: > 8 11 Explian: Just be careful the macro is extending the expression rather than calling a function call. --- * Use typedef to declare "foo" as an array of 10 pointer to functions taking as input two constant generic pointer and returning an integer in C++ ```cpp typedef int (*foo[10])(const void *, const void *); ``` or ```cpp using foo = int (*[10])(const void *, const void *); ``` --- * Define in C++ a pointer that points to the element `a[5][10]` of the array "`int a[10][20][30][40];`" named p. ```cpp auto p = &a[5][10]; ``` or ```cpp int (*p)[30][40] = &a[5][10]; ``` --- * In C++, when is the default constructor automatically generated by the compiler? > §11.4.3 Special member functions Default constructors (11.4.4.1), copy constructors, move constructors (11.4.4.2), copy assignment operators, move assignment operators (11.4.5), and prospective destructors (11.4.6) are special member functions. >> [Note: ==The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them.== The implementation will implicitly define them if they are odr-used (6.3) or needed for constant evaluation (7.7). — end note] >> > An implicitly-declared special member function is declared at the closing } of the class-specifier. Programs shall not define implicitly-declared special member functions. ref: [C++20 std](https://isocpp.org/files/papers/N4860.pdf) --- * What is the difference between struct and class in C++. > All `struct`'s members are public by defualt. > All `class`'s members are private by default. Except for the special member functions. --- * What is the difference between a pointer and the name of an array in C++? Array is a pointer to a address for some spaces of contigous memory. Pointer is a pointer to a memory address. $Array = Pointer$ $Array \not\equiv Pointer$ For example: ```cpp= int arr[10]; sizeof(arr); // 40 sizeof(&arr); // 8 in 64-bit machine ``` :::info 還沒讀完: [C++17 standard](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf) [Array declaration](https://en.cppreference.com/w/cpp/language/array) [Value category](https://en.cppreference.com/w/cpp/language/value_category) > About prvlaue, xvalues, rvalue expressions... ::: --- * What would be the output of the following C++ program? Why? ```cpp= #include <iostream> using namespace std; class A { public: A(int i) : v(i) { cout << "A::A(" << i << ") called" << endl; } ~A() { cout << "A::~A() called" << endl; } operator bool() { return v != 0; } private: int v; }; int main() { int i = 1; while (A a = i) { i = 0; } return 0; } ``` Output: > A::A(1) called > A::~A() called > A::A(0) called > A::~A() called Explain: `A a = i` is an initialization of `A` to `a`. And the `v(i)` of the constructor `A(int i) : v(i) {...}` is also an initialization of the variable `v` for `int` type. --- * What is the major difference between a reference parameter and a constant reference parameter? We cannot modify the constant reference parameter's value in compile time. But non-const could. :::info NOTE: We can use the [buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) or some [special hijacking method](https://accu.org/journals/overload/28/156/harrison_2776/) to modify any variable or function in run time. ::: --- * Give the definition of the special member functions and their names as we discussed in the classroom that would in some circumstances be implicitly defined by a C++ implementation for a class, say, C, as given below. ```cpp= struct C { std::string s; }; ``` Sol: :::spoiler ```cpp= C() : s() {} // default ctor ~C() {} // dtor C(const C &_a) : s(_a.s) {} // copy ctor C(C &&_a) : s(std::move(_a.s)) {}// move ctor C &operator=(const C &_a) { // copy assignment operator if (&a != this) s = _a.s; return *this; } C &operator=(C &&_a) { // move assignment operator if (&a != this) s = std::move(_a.s); return *this; } ``` The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. :::