多态 多重继承 接口实现 虚方法不要用内联实现

这样不行,没有成员函数的实现:

#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();

};

posted @   Bigben  阅读(51)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2018-01-10 spring boot集成ehcache 2.x 用于hibernate二级缓存
2018-01-10 Spring 整合 Hibernate 时启用二级缓存实例详解
2015-01-10 sliding menu
点击右上角即可分享
微信分享提示