C++ Primer Chapter 15 OOP 作者: rin 时间: October 14, 2021 分类: C++ # Ch15 OOP ## 15.1 An Overview OOP is based on 3 fundamental concepts: 1. **Data abstraction**: Separate interface from implementation 2. **Inheritance**: Define classes that model the relationships among similar types. 3. **Dynamic binding**(run-time binding): Use objects(*virtual function*) while ignoring the details of thow they differ (through *pointers* or *references* to the base class). Inheritance: - A derived class must declare each inherited menber function it intends to override. - The access specifier in derivation list is *optional*, default value = `private` for `class`, `public` for `struct` - A derived class ctor initializes its *direct* base class only. - Base part and derived part in an object are not guranteed to be stored contiguosly. ## 15.3 Virtual Function Virtual function: - Root of an inheritance hierarchy almost define a virtual dtor `virtual ~dtor(){}`. - Any *nonstatic* member func (other than ctor) can be virtual - If a virtul func with default args is called, which version of args to use is denpent on the static type. Thus, such functions should use same default args. P607 - Virtual func declared in base class is implicitly virtual in derived classed: ```c++ // inside base class: virtual void func() {} // inside derived class: void func() = 0 // omitting keyword virtual is OK ``` --- ## 15.4 Abstract Base Classes - We can provide a definition for a *pure virtual* function (outside the class). It is used to provide some common operations. [c++ - Defining pure virtual functions outside the class definition - Stack Overflow](https://stackoverflow.com/questions/29449492/defining-pure-virtual-functions-outside-the-class-definition) ```c++ // outside the class void B::func() { /*common operations */} void B::~B() { /* some cleaning up *} ``` - Abstruct base class defines an *interface* - A derived class ctor initializes its *direct* base class only. --- ## 15.5 Access Control & Inheritance - Members and **friends** of a derived class can access this (derived) class's protected members. But the friends can't access the members of base class. - In fact, a derived type object has no special access to the protected *ordinary* base type object. ``` c++ class B { protected: int v; }; class D : public B { friend void func(D&); // can access D's protected member D::v friend void func(B&); // can't access B's protected member B::v void func(B& b){b.v=1;} // no direct access to ordinary object's v void func() {v=1;} // OK }; ``` ### Dervied-to-Base Conversion Accessibility depends on *who* is using the conversion and the *access specifier* in derivation. 1. The User Code: public 2. The Member func and Friend func of the derived class: `public`, `protected`, `private`==<-why private works== #what 3. The Member func and Friend func of the derived class of derived class: `public`, `protected` ```c++ class B { protected: int v = 1; }; class D :/*__what to fill_____*/ B { void member_func() { D d; // CASE#2: derived-to-base conversion in MEMBER FUNC & FRIENDS B b = (B)d; // OK: public, protected, private } friend void friend_func(); // CASE#2: same for the FRIENDS }; class AnotherClass : protected D { void func() { D d; // CASE#3: derived-to-base conversion in the Class derived from D B b = (B)d; // OK: public, protected (both for the D->B and AC->D inheritance) } }; int main() { D d; // CASE#1: derived-to-base conversion in USER CODE B b = (B)d; // OK: only public } ``` --- ## 15.6 Class Scope under Inheritance - Name Lookup happens before Type check. The base functions are hidden even if the functions in derived class have different paramete list. - Once override one of the (Base class's) overloaded functions, other overloaded functions will be hiden. Use `using` to bring all versions: https://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-function-in-c ```c++ #include using namespace std; struct B { virtual void a(int) { cout << "B::a(int)" << endl;}; virtual void a(int, int) { cout << "B::a(int,int)" << endl;}; }; struct D: public B { void a(int) { cout << "D::a(int)" << endl;}; void a(int,int,int){ cout << "D::a(int,int,int)" << endl;};; using B::a; // bring all overloded function from B }; int main() { D d; int i = 0; d.a(i); // OK, D::a(int) // d.a(i, i); // NO matching function without `using` d.B::a(i,i); // OK, B::a(int,int) d.a(i, i, i); // OK, D::a(int,int,int) } ``` --- ## 15.7 Ctor and Copy Control - Use `using` to "inherit" ctors from a class's *direct* base class. Compiler generates ctors with a same parameter list as the ctor in the base class. - Unlike `using` ordinary members, this doesn't change the ctors access level and propertirs(explict, constexpr) - Base ctors with default parameters are split into serveral ctors withou default parameters #what - default copy, move ctors are not ingerited - a class that only contains inherited ctors will have a synthesized default ctor. - 标签: C++