final
用final关键字限制某个类不能被继承,或某个虚函数不能被重写。如果修饰函数,只能修饰虚函数,要放在类或函数后面。
#if 0
class A final
{
public:
A() { cout << "A" << endl; }
};
#endif
#if 0
class A
{
public:
virtual void fn()final {}
};
class B :public A
{
public:
virtual void fn() //fn无法被子类重写
{
cout << "B::fn" << endl;
}
};
#endif
override
它好像在说:我要重写!!
确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同样也明确表明将会重写基类的虚函数,还可以防止因疏忽把本来想重写的虚函数声明成隐藏。既可以保证重写虚函数的正确性,又能提高代码可读性。和final一样也要放后面,要写在子类中加,加的前提是基类有这个虚函数。
class A
{
public:
virtual void fn() {}
};
class B :public A
{
public:
virtual void fn()override
{
cout << "b::fn" << endl;
}
};
void main()
{
A a;
B b;
b.fn();
}
单例模式--只能创建一个对象
1)将构造函数定义为private或protected
2)static不需要对象调用,里面没有隐含的this指针
3)如果要求只能创建一个对象,要将拷贝构造函数和赋值删除,static成员函数要加引用
class A
{
protected:
A() { cout << "A" << endl; }
A(const A&) = delete;//删除拷贝构造
public:
A& operator = (const A& a) = delete;//删除赋值,有赋值它可以创建新对象
/* {
cout << "A operator = " << endl;
return *this;
}*/
public:
static A& fn()
{
static A a;
return a;
}
};
void main()
{
//A a;
A &b = A::fn();
A& bb = A::fn();
// A* p = (A*)malloc(sizeof(A));
// *p = b;
}
动态联编和静态联编(晚捆绑和早捆绑)
动态:在程序执行的时候才将函数实现与函数调用关联起来
静态:对象名加“.”成员选择运算符,去调用对象虚函数,则被调用的虚函数是在编译和链接时确定的
1.设计一个不能在外部环境中创建该类的对象
将基类的构造函数设计成private,在外界也不能创建对象
class A
{
private:
A() {}
};
2.设计一个不能被继承的类
class A final
{
public:
A() { cout << "A" << endl; }
};
3.设计一个不能被继承的类,可以在外部环境中创建该类的对象
class A final
{
public:
A() { cout << "A" << endl; }
};
4.设计一个能被继承的类,但不能在外部环境中创建该类的对象
不能定义基类(将基类的构造,拷贝构造,赋值protected),但是可以定义子类对象
class A
{
protected:
A() {}
A(const A&) {}
A& operator=(const A&) { return *this; }
};
class B :public A
{
};
void main()
{
//A a;
B b;
B b1 = b;
B b2(b1);
}