多态 多重继承 接口实现 虚方法不要用内联实现
这样不行,没有成员函数的实现:
#include <iostream>
using namespace std;
class Base1 {
public:
virtual void b1();
};
class Base2 {
public:
virtual void b2();
};
class Base :public Base1, public Base2 {
public:
void b1() override { cout << "b1 call\n"; }
void b2()override { cout << "b2 call\n"; }
};
1,加上实现就可以:等于做了基类的实现模范
没有把虚函数实现直接放在头文件的申明里面,是因为chrome规范不让!!!
大部分情况如果申明和实现不在一起,需要分开定义。
这说明一定要有Base1,Base2的实现。只有派生类有实现也不行!
这有个毛病就是在大的工程里面,如果不同模块中有类实现了这个接口,导致每个模块都需要有这个接口的实现。否则编译不通过。 即每个模块都要有下面的接口实现代码。这个实现需要分散在不同的模块,最后小模块要合并到一起。竟然编译通过了。
可能编译器找到一个实现后,屏蔽或者就不去查找其他实现了。
void Base1::b1() {
cout << "nnn b1 call\n";
}
void Base2::b2() {
cout << "nnn b2 call\n";
}
2,或者 将接口 Base1,Base2 定义成虚函数,便可以:
class Base1 {
public:
virtual void b1()=0;
};
class Base2 {
public:
virtual void b2()=0;
};
完整示例:
#include <iostream>
using namespace std;
class Base1 {
public:
virtual void b1();
};
class Base2 {
public:
virtual void b2();
};
class Base :public Base1, public Base2 {
public:
void b1() override { cout << "b1 call\n"; }
void b2()override { cout << "b2 call\n"; }
};
int main() {
//指针
Base bb;
Base* b = &(bb);
Base1* f1 = (Base1*)b;
f1->b1();
Base2* f2 = (Base2*)b;
f2->b2();
//用引用
Base1& bbb = bb;
bbb.b1();
}
将Base1接口强制转成 Base2,这样是不行地:
奇怪,即使base1接口类没有b2函数,强制转成Base2后,还是可以调用b2(),但实际还是跑的b1().
Base bb;
Base* b = &(bb);
Base1* f1 = (Base1*)b;
f1->b1();
Base2* f2 = (Base2*)f1;//这里f1是Base1的
f2->b2();//还是执行的 b1函数
改成这样可以,先转回具体实现类base,再转成抽象类Base1:
Base* ori = (Base*)f1;
Base2* f2 = (Base2*)ori;
f2->b2();
Virtual Method Out-of-lining
Virtual methods are almost never inlined in practice. Because of this, methods on a base class will be emitted in each translation unit that allocates the object or any subclasses that don't override that method. This is usually not a major gain, unless you have a wide class hierarchy in which case it can be a big win (http://codereview.chromium.org/5741001/). Since virtual methods will almost never be inlined anyway (because they'll need to go through vtable dispatch), there are almost no downsides.
If you get the error:
- virtual methods with non-empty bodies shouldn't be declared inline
It's because you wrote something like this:
class BaseClass {
public:
virtual void ThisOneIsOK() {}
virtual bool ButWeDrawTheLineAtMethodsWithRealImplementation() { return false; }
};
And can be fixed by out of lining the method that does work:
class BaseClass {
public:
virtual void ThisIsHandledByTheCompiler() {}
virtual bool AndThisOneIsDefinedInTheImplementation();
};

浙公网安备 33010602011771号