参考 虚函数 函数重载有以下要求:
基类中的函数必须是虚函数
基类和派生类中的函数名字必须完全相同(析构函数例外)、
基类和派生类中的函数形参型别必须完全相同
基类和派生类中的函数常量性必须完全相同
基类和派生类中的函数返回值和异常规格必须兼容
c++11又多了一条:
引用饰词 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> using namespace std;class mydata { public : mydata () { cout << "constructor" << endl; } ~mydata () { cout << "destructor" << endl; } mydata (mydata && param) { cout << "move constructor" << endl; } mydata (mydata & param) { cout << "copy constructor" << endl; } mydata operator =(mydata && param) { cout << "move operator = " << endl; } }; class myclass { public : mydata _m; myclass ():_m() { } mydata& data () & { cout << "--data() &" << endl; return this ->_m; } mydata data () && { cout << "--data() &&" << endl; return std::move (this ->_m); } }; myclass makemyclass () { return myclass (); } int main () { myclass my; auto a1 = my.data (); auto a2 = makemyclass ().data (); }
override c++11允许在派生类的成员函数末尾添加override,表明派生类将要重写该函数,编译器会校验重写的规则,避免了一些隐晦的含义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream> using namespace std;class base {public : virtual void func1 () const { cout << "base: virtual void func1() const" << endl; } virtual void func2 (int x) { cout << "base: virtual void func2(int x)" << endl; } virtual void func3 () & { cout << "base: virtual void func3() &" << endl; } void func4 () const { cout << "base: void func4() const" << endl; } }; class derived : public base {public : virtual void func1 () { cout << "derived: virtual void func1()" << endl; } virtual void func2 (unsigned int x) { cout << "derived: virtual void func2(unsigned int x)" << endl; } virtual void func3 () && { cout << "derived: virtual void func3() &&" << endl; } void func4 () const { cout << "derived: void func4() const" << endl; } }; #if 0 class derived2 : public base {public : virtual void func1 () override ; virtual void func2 (unsigned int x) override ; virtual void func3 () && override ; void func4 () const override ; }; #endif class derived3 : public base {public : virtual void func1 () const override ; virtual void func2 (int x) override ; virtual void func3 () & override ; }; derived makederived () { return derived (); } int main () { derived der; base *bas = &der; bas->func1 (); unsigned int x = 0 ; bas->func2 (x); bas->func3 (); bas->func4 (); }
final
final跟在类定义后面,表示该类不能被继承:class test1 final
final不能修饰非虚函数
final在基类的虚函数后面,表示派生类不可以重载该函数
final在派生类的虚函数后面,表示派生类的其他派生类不能重载该派生类的此函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 struct Base { virtual void foo () ; }; struct A : Base{ void foo () final ; void bar () final ; }; struct B final : A { void foo () override ; }; struct C : B { };
对于上面#a的解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;struct Base { virtual void foo () { cout << "base: foo()" << endl; } }; struct A : Base{ void foo () final { cout << "A: foo()" << endl; } }; int main () { A a; Base *p = &a; p->foo (); }
A: foo()
总结
override与final都不是语言关键字(keyword),只有在特定的位置才有特别含意,其他地方仍旧可以作为一般指示字(identifier)使用。override仅出现在成员函数的末尾才有意义。其他地方使用意义就变了:
1 2 3 4 void override (void ) { cout << "override" << endl; }
为意在重写的函数添加override
成员函数引用饰词使得对于左值和右值对象(*this)的处理能够区分开来
ending