# Leture 5 Classes Class --- 類別的基本要素: 1. 抽象化(Abstraction):將介面 (interface) 和實作 (implementation) 的分離,只提供與使用者介面有關的資訊,將背後實作區塊隱藏起來。 2. 封裝(Encapsulation):把不需要透露給外部的屬性 (data) 、操作屬性的行為 (function)隱藏起來,讓外部無法存取避免干擾和誤用。 Class designer 思考class如何被實作,Programmers 思考這個物件類別可以做到什麼事 Abstract Data Types (ADT) 抽象資料型別,是一堆 data 和操作 data 的 operation Access Control and Encapsulation --- In C++ we use access labels to enforce encapsulation. A class may contain zero or more access labels: * **public** label are accessible to all parts of the program. * **private** label are accessible by the member functions of the class, but are not accessible to codes that use the class. The private sections encapsulate (e.g., hide) the implementation from code that uses the type. * **protected** label are inaccessible outside the class but they can be accessed by any subclass(derived class) of that class. These labels remains in effect until the next access label is encountered or the closing right brace of the class body is seen. * `struct` keyword, members defined before the first access label are public. * `class` keyword, members defined before the first access label are private. **A typical class definition has the following form:** ```C++ class className { private: data member declarations //data members in the private section public: member function prototypes //member functions in the public section }; ``` Member Function & Non-member Function --- * **Member functions** must be declared inside the class. However, member functions may be defined inside the class itself or outside the class body.++In general, if the function body consists of more than three lines, we should do it outside the class.++ * **Nonmember functions** are part of the interface, declared and defined outside the class. ==IMPORTANT== * When defining member functions outside the class, must used " :: " operator to tell the compiler which class they belong to. **In-class Coding Excercise** A sample client code and output look like : ```C++ #include <iostream> #include "Person.h" using namespace std; int main() { Person p; p.setName("John"); p.setAge(25); cout << "Name: " << p.getName() << " age: " << p.getAge() << endl; return 0; } ``` ![](https://i.imgur.com/aAlRBpw.png) **More Concept** --- 1. **"this" & "->"** The "this" pointer is an implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to the invoking object. Friend functions do not have a this pointer, because friends are not members of a class. **Common Scenario** * `this->`存取 member 內的資料或函數 * `*this`運算式通常用來從成員函式傳回目前物件 * 指標 `this` 也可用來防範自我參考 `if (&Object != this)` 2. **Chained Operations** Consider the previous exercise on the class Person. If we would like to concatenate a sequence of set actions into a single expression so we can do: ```C++ Person p; p.setName("John").setAge(25); p.setAge(25).setName("John"); ``` In order to do so, we can modify `setAge` and `setName` implementation as follow: ```C++ Person& setName(const std::string& s){name = s; return *this;} Person& setAge(unsigned num){age = num; return *this;} //we used *this return the object on which the function was called ``` 3. **const function** The const that follows the parameter listed in the declarations of a member functions is called a const member function. Which means, a const member function ++cannot change the object on which it is called++. Friends --- A class can allow another class or function to access its nonpublic members by making that class or function a friend. HOW:Making a friend declaration for that function. ```C++ #ifndef CIRCLE_H #define CIRCLE_H #include <iostream> class Circle { public: //Making a friend declaration friend std::ostream &print(std::ostream &os, const Circle &c); Circle() = default; Circle(double r){radius = r;} void setRadius(double r){radius = r;} double getArea() const {return PI*radius*radius;} private: double radius = 0.0; const double PI = 3.14159; }; std::ostream &print(std::ostream &os, const Circle &c); #endif // CIRCLE_H ``` ==KEY NOTICE== The ++IO classes++ are types that ==cannot be copied==, so we may only ==pass them by reference==. Moreover, reading or writing to a stream changes that stream, so both functions take ordinary references, not references to const. Constructors --- Classes control object initialization by defining one or more special member functions known as constructors. In C++, constructors are * member functions * named as the same name as the class * with no return type * may have a parameter list If class does not explicitly define any constructors, the compiler will implicitly define the ==default constructor== for us. This compiler-generated default constructor is known as the ++synthesized default constructor++.It initializes each data member of the class as follows: * If there is an in-class member initializer, use it to initialize the member. * Otherwise, default-initialize the member. ```C++ class Circle { public: //default behavior Circle() = default; //constructor initializer list Circle(double r):radius(r){} //another way to write a constructor that has parameters //Circle(double r){radius = r;} private: double radius = 0.0; const double PI = 3.14159; }; ```