2.9 Content: 1. Revision Of OOP 2. Name Equivalence 3. Forward declaration 4. Member Initializer List (MIL) 5. Seperate Compilation 6. Inline function 7. "this" pointer 8. Parameter passing Function prototype = function declaration e.g. print_age() const; --> declaration print_age() const { ....... -----> definition } Helper function (Global function or private function) Struct vs function struct{...} = class(public: ...) class{...} = struct(private: ...) "Name Equivalence": class W { int a;} class W { int b;} // Error! Double definition! // Name Equivalence! class X {int a;} class Y {int a;}. // OK! although same attribute's name class Cell { int info; Cell* next; // OK , We can use class's POINTER inside its own definition Cell obj; // NO! class not defined yet! // ERROR! Has incomplete type "cell" } Forward declaration class Cell; class list{ Cell* cellptr; // OK ! we have forward declaration Cell cellobj; // No! incomplete class! // Even we have class definition later , this is still an error! // since at this "list"'s definition, "Cell" is always incomplete } class Complex { private: float real; float imag; public: void print() const { cost< data members are "undefined" } int main(){ int a; // here a is undefined : trash value } int a; // here a is undefined but has value 0 ( 0-initialization) class Complex { private: float real = 1.3; float imag = 0.5; // In-class initializer public: Complex() { real = 0.1 ; imag = 0.2;} // *** Constructor overrides in-class initializers! void print() const { cost< parameter passing -> return by value } IF INLINE: Inline => UNFOLD (The content in function) then above equals to : int main() { int a = 10; a++ ; // no parameter passing , no return by value // faster! } inline with Class: if we want to declare a function inline: 1. Inline function within the class body -> inline is optional! 2. Outside class body ( BUT WITHIN THE SAME FILE): if we want declare "inline" , then "inline" keyword is MANDATORY!: e.g. class Person{ .....} Person* Person::child() const{return child;} // not inline inline Person* Person::child() const{return child;} // inline 3. Outside class body ( in Seperate file ) ,all function is non-inline!: --> WE CANNOT USE INLINE IN SEPERATE FILE! Scope operator "::" global Scope operator :: class scope: Class_name:: "this" pointer : call data member Parameter passing: Pass-by-value: void fun(int a){ cout< a, b = 2; 3. Return by reference: int& f2(int&a){ // a is a alias of _ a++; return a; } int& ref = f2(x); // OK f2(x)++; // OK ( x-ref-> a --> a++ -ref-> f2(x) --> f2(x)++ ) 4. PBV+RBR int& f3(int a){return a;} // Error , a is a local variable , will be destroyed after function call 5. PBP void f(int* p) { int p = new int;} int main() { int * p = nullptr; // p ---> nullptr int x = 123; p = &x; // p ---> x's address f(p); // f(int* p) { p = new int;} --> this "p" is a LOCAL VARIABLE! // f's p --> new int's address // 可以读,不能改 (改变不会传到函数体外) // after f(p) : p ---> x's address return 0; } WHY? : 指针按值传递! local_p is copyed from p --> copying address stored in pointer p = new int; 改变local_p's address--->原pointer p's address不改变 f() 结束后,原pointer p's address不改变 ANOTHER CASE: void f(int* p) { *p = 999;} int main() { int * p = nullptr; // p ---> nullptr int x = 123; p = &x; // p ---> x's address f(p); // f(int* p) {*p = 999; } --> local_p is copyed from p --> copying address stored in pointer --> they have the same address --> the actual (*P) is changed! // after f(p) : *p = 999; // 对指针本身->修改穿不到函数体外 // 对指针指向的obj->地址相同 可以传到函数外 return 0; } 6. RBP int* f() { int *p = new int; return p; } int main() { int* p = nullptr; int x = 123; p = &x; p = f(); cout<< "after f()" << p < create a copy--> if we do (*this).add then the original object will not be changed again // Return by value, by reference --> if we do (*this).add then the original object will be changed again Const: 声明: 不改变Data member Calling Object const Member function non-const Member function ---------------------------------------------------------------------------- const Obj Okay NO non-const obj Okay Okay // Const Obj only can call Const member function Passing Obj as const Function Argument as non-const Function Argument ------------------------------------------------------------------------------ literal const Okay NO // literal const 的生命周期短,函数不能修改他 (如果修改,做出的修改放在哪?) const obj Okay NO non-const obj Okay Okay ”const obj“ & ”literal const“ cannot be passed in non-const function! ”可以减小权限,不能增加权限“ void cbr(int& a){} void cbr(const int&a ){} int main() { int x = 50 ; const int y =30; cbr(x) //Okay cbcr(x) //Okay cbr(y) //No cbcr(y) //Okay cbr(123) //Okay cbcr(123) //Okay } "const" keyword in Class ---> “read-only function” --> cannot mutate class member const float PI = 3.14159 #define PI 3.1416 const pointer: Any const to the left of * refers to the object being pointed to Any const to the right of * refers to the pointer itself int * ptr Case1 -> const int* ptr // 常量整数的指针 Case2 -> int const* ptr // 常量整数的指针 "Any const to the left of * refers to the object being pointed to" Case 1,2 -> Pointer to "constant int" Case3 -> int* const ptr // 整数的常量指针 "Any const to the right of * refers to the pointer itself" -> Constant pointer to int ( " fixed ") "Any const to the left of * refers to the object being pointed to" "Any const to the right of * refers to the pointer itself" Remark: int* const * p = const (int*) * p 指向“ 常量int*” 的指针 const int * ptr; int x = 10; ptr = &x; cout<< *ptr ; // Okay! (*ptr) = 20; // Error! We regard (*ptr) as a constant int! x++; // Okay , x is modifiable! (*ptr)++; // NO ! // x cannot be modified through ptr , but can be modified through x itself For "int* const", Initialization is a must! --> int* const ptr; // ERROR! int x = 10; int* const ptr = &x; // Okay int y = 20; int* const ptr = &y; // ERROR, It suppose to be fixed! i.e. No re-binding! (*ptr) = 100; // OKAY , (*ptr) is regarded as modifiable const int* const ptr; ptr = &y; -> ERROR (*ptr) = 100; -> ERROR cout<< *ptr; // Okay -> READ-ONLY! char* strcpy(char* dest, const char* src) --> Ensure that we cannot modify Source! char s1[] = "C++" char s2[20]; strcpy(s2,s1) strcpy(s2,"c++")