何时使用protected
使用protected使得子类可以直接访问父类成员,意味着如果你对protected成员作修改,你可能要修改父类和所有子类
使用private意味着对实现细节的封装
一般只需要使用public inherit
在子类redefine函数时,access modifier只取决于子类中这个函数的modifier,与父类中的无关
Overload resolution
class Base
{
public:
void print(int) { std::cout << "Base::print(int)\n"; }
void print(double) { std::cout << "Base::print(double)\n"; }
};
class Derived: public Base
{
public:
void print(double) { std::cout << "Derived::print(double)"; } // this function added
};derived.print(1)会匹配到derive中的print,为了改变这一行为,推荐在derive中使用using引入base的print(int)
using还会根据他自己在哪个access modifier修饰下,改变引入函数的modifier,并且不难认为using会将所有该函数的重载的modifier都修改
Access controls are not enforced at runtime.
class A{
public: virtual void fun()
};
class B : public A{
private: virtual void fun()
};
int main()
{
B b {};
b.fun(); // compile error: not allowed as B::fun() is private
static_cast<A&>(b).fun(); // okay: A::fun() is public, resolves to private B::fun() at runtime
}mixin
mixin是用来被继承,在继承它的类中增加一些属性的。mixin的名字表达了他不应该instantiated on its own
mixin通常不使用虚函数而使用模版
Curiously Recurring Template Pattern
一个类继承一个模版类,使用他自己作为模版参数
template<class Z>
class Y {};
class X : public Y<X> {};Diamond Problem
菱形继承
虚函数
使得函数总是解析到最derived版本
使得基类指针和引用调用派生类函数
If a function is virtual, all matching overrides in derived classes are implicitly virtual.
because the override specifier implies virtual, there’s no need to tag functions using the override specifier with the virtual keyword
在基类中使用virtual,在子类中使用override即可
编译期多态
函数重载解析和模版解析
early binding/static binding
编译期解析
运行期多态
late binding/dynamic dispatch
函数指针
虚函数解析
covariant return types
允许虚函数的返回指针/引用类型不同,是所override函数的子类
vptr是最base的类的成员,是一个指向虚函数表的指针,它实际占用类的内存(和this不同)。
纯虚函数也可以有定义,这仍然会对子类的定义有要求。这个定义可以被子类使用
析构函数可以是纯虚的,但必须有定义
virtual base class
使得菱形继承时共用基类且基类只被构造一次
virtual base class会先于所有non virtual的构造
Frankenobject
int main()
{
Derived d1{ 5 };
Derived d2{ 6 };
Base& b{ d2 };
b = d1; // this line is problematic
return 0;
}由于拷贝构造函数不是虚函数,只复制了d1的base部分
linux堆空间分配系统调用brk和mmap
运行库管理堆空间分配,避免频繁系统调用
malloc对小对象会在现有空间中直接寻找可分配的块,对大对象直接使用mmap
Which book is best for system programming (APUE vs TLPI)? : r/kernel (reddit.com)