oop(面向对象) 三大特性 封装、继承、多态性

对象组合:用已有的对象来组合出新的对象(这是一种软件重用的方式)
什么东西在哪里用什么方式访问就叫内存模型

objects can be used to build up other objects.

composition
ways of inclusion:

    1: fully        // 这种方式反映到代码本身就是成员变量就是对象(包含)
    2: reference    // 这种方式则是成员变量是指针   (外部)

Embedded bjects (嵌套的对象)
all embedded objects are initialized
    1: if the default constructor is called, you don't supply the arguments,
        and there is a default constructor(or one can be built)
    如果用无参构造函数初始化就不能给出参数,而且要有一个这样的无参构造函数
constructor can have initialization list    构造函数可以有初始化列表
    1: and number of objects separated by commas
    2: is optional
    3: provide arguments to sub-constructor     // 给子构造函数提供参数
翁恺老师要求:任何类的成员对象都在初始化列表里初始化

resuing the interface   重用接口
inheritance isto take existing class, clone it, and then make additions and modifications to the clone.
继承产生的新类是原来类的超集,当去继承一个类的时候要对那个类进行扩充
base class 基类 super class 超类 parent class 父类
derive class 派生类 sub calss 、child class 子类

子类继承父类,子类具有父类的全部属性
父类的私有成员在子类中是存在的,但是不能直接访问的
protected 意思是受保护的,只能在这个类中或他的子类中访问
protected 可以留给子类一些接口,让子类可以通过protected 中的接口来访问 private 中的成员

构造函数不能主动调用
先构造的后析构
父类的构造函数调用必须放在初始化列表里
顺序是按照声明的顺序,而不是按照写在初始化列表里的顺序。
父类先初始化,然后成员变量是按照写在初始化列表里的顺序初始化

More on constructor
base class is always constructed first
if no explicit arguements are passed to base class
    default constructor will be called
Destructors are called in exactly the reverse order of the constructors
    析构函数的调用顺序和构造函数相反

如果在父类中有一个函数的几个不同的形式(函数之间重载),在子类中出现了与父类中重复的函数(名字,参数表都一样)
那么子类当中就只有那一个函数了或者说只有子类自己的,父类的那些函数就被隐藏掉了。
只有C++是这样干的,别的oop语言都不这样干

learning record code:

#include <iostream>
#include <string>
using namespace std;

class Name {
    private:
        string name;
    public:
        Name(string s) : name(s) {}     // 初始化列表,构造函数
        void set(string s) { name = s; }
        void print() { cout << name << endl; }
};
class Count {
    private:
        int money;
    public:
        Count(int num) : money(num) {};
        void print(){ cout << money << endl; }
};

class Saving {
    private:
        Name s_name;
        Count s_count;
    public:
        Saving(const string name, const int num) : s_name(name), s_count(num) {}
        void print()
        {
            s_name.print();
            s_count.print();
        }
};

class A {
    public:
        A() : i(0) { cout << "constructor called" << endl; }
        ~A() { cout << "destructor called" << endl; }
        void print() { cout << i << endl; }
    protected:
        void set(int num) { i = num; }
    private:
        int i;
};

class B : public A {        // B 是 A 的子类
    public:
        void f() 
        { 
            set(20); 
            // i = 30; 
            print(); 
        }
};

class Employee {
    protected:          // 子类可以直接访问这两个成员变量
        std::string m_name;
        std::string m_ssn;
    public:
        Employee(const std::string &name, const std::string &ssn);
        const std::string & get_name() const;
        void print(std::ostream &out) const;
        void print(std::ostream &out, const std::string &msg) const;
};
Employee::Employee(const std::string &name, const std::string &ssn) : m_name(name), m_ssn(ssn) 
{
    // initializer list set values
}
inline const std::string & Employee::get_name() const
{
    return m_name;
}
inline void Employee::print(std::ostream &out) const
{
    out << m_name << endl;
    out << m_ssn << endl;
}
inline void Employee::print(std::ostream &out, const std::string &msg) const
{
    out << msg << endl;
    print(out);
}

class Manager : public Employee 
{
    private:
        std::string m_title;
    public:
        Manager(const std::string &name, const std::string &ssn, const std::string &title);
        const std::string title_name() const;
        const std::string & get_title() const;
        void print(std::ostream &out) const;
};
Manager::Manager(const std::string &name, const std::string &ssn, const std::string &title = "")
    : Employee(name, ssn), m_title(title) { }       // manager class constructor

inline const std::string Manager::title_name() const
{
    return string(m_title + ": " + m_name);     // access base m_name
}
inline const std::string & Manager::get_title() const
{
    return m_title;
}
inline void Manager::print(std::ostream &out) const
{
    Employee::print(out);   // 调用父类输出函数
    out << m_title << endl;
}

int main()
{
    // Saving tm("zhangchenglong", 1000000000);
    // tm.print();

    // B b;
    // // b.set(10);
    // b.print();
    // b.f();


    Employee bob("Bob jones", "55-44-000");
    Manager bill("Bill Smith", "66-55-123", "Important person");

    string name = bill.get_name();
    
    // string title = bob.get_title();      错了,bob是一个Employee
    cout << bill.title_name() << '\n' << endl;
    bill.print(cout);
    bob.print(cout);
    bob.print(cout, "Employee: ");
    // bill.print(cout, "Employee");        不存在这个函数


    return 0;
}