在基类体内声明但通过派生类调用的函数的内联
Posted
技术标签:
【中文标题】在基类体内声明但通过派生类调用的函数的内联【英文标题】:Inlining of functions declared inside the base class body but called through a derived class 【发布时间】:2017-03-04 20:29:16 【问题描述】:情况是这样的。我在头文件中声明了一个基类,其中包含一些受保护的数据成员和一些公共 getter 函数(单行正文)。没有虚拟方法。从它派生出一个子类,并定义了自己的构造函数,其定义放在对应的cpp文件中。
是否会内联通过派生类的对象调用 getter 函数?
编辑:这是我的代码。
// quad.h
class QuadratureRule
protected:
int ngauss;
Array points;
Array weights;
public:
QuadratureRule(int ng) : ngauss(ng)
double getweights(int ig) const
return weights[ig];
;
class Quadrature2D : public QuadratureRule
public:
Quadrature2D(int ng);
;
和
//quad.cpp
#include "quad.h"
Quadrature2D::Quadrature2D(int ng) : QuadratureRule(ng)
// initialize arrays in a certain way
当 Quadrature2D
类的对象调用时,我希望 getweights
内联。
另外,我使用的是 GCC g++ 5.4 和 6.3。
【问题讨论】:
虽然您的问题可能很清楚,但代码能说明问题。可以提供代码演示吗? 很可能,是的。唯一确定的方法是检查生成的代码。 (没有 C++ 需要函数内联的情况;这取决于实现。) 没有理由不应该内联您的代码,在这方面,与其他函数相比,您的情况并没有什么特别之处。但是,不能保证函数会被内联。只需检查您的装配即可。 【参考方案1】:编辑:
我一直在检查它,似乎如果你打开优化它实际上会被内联。但正如人们在 cmets 中已经说过的那样,这真的取决于实施。例子:
Code without optimizations
Code with optimizations
你让我很好奇,所以我查了一下。 这是我的程序:
// base.h
include <iostream>
class Base
int x;
int y;
public:
Base(int x = 0, int y = 0) : x(x), y(y)
int getx() const return x;
void setx(int x) this->x = x;
int gety() const return y;
void sety(int y) this->y = y;
;
还有:
// derived.cpp
#include "base.h"
class Derived : public Base
int z;
public:
Derived(int x = 0, int y = 0, int z = 0) : Base(x, y), z(z)
;
using namespace std;
int main()
Derived d(1, 2, 3);
cout << "d.x == " << d.getx() << ", d.y == " << d.gety() << endl;
d.setx(4);
d.sety(4);
cout << "d.x == " << d.getx() << ", d.y == " << d.gety() << endl;
return 0;
在 gcc 6.3 上编译:
g++ -Wall -Werror -g -pedantic-errors -o derived derived.cpp
这是 objdump 的一部分,在 main()
内:
a2b: e8 1a 01 00 00 call b4a <_ZN4Base4setxEi> ; A call to setx()
a30: 48 8d 45 e0 lea rax,[rbp-0x20]
a34: be 04 00 00 00 mov esi,0x4
a39: 48 89 c7 mov rdi,rax
a3c: e8 33 01 00 00 call b74 <_ZN4Base4setyEi> ; A call to sety()
a41: 48 8d 45 e0 lea rax,[rbp-0x20]
a45: 48 89 c7 mov rdi,rax
a48: e8 15 01 00 00 call b62 <_ZNK4Base4getyEv> ; A call to gety()
a4d: 89 c3 mov ebx,eax
a4f: 48 8d 45 e0 lea rax,[rbp-0x20]
a53: 48 89 c7 mov rdi,rax
a56: e8 df 00 00 00 call b3a <_ZNK4Base4getxEv> ; A call to getx()
假设我没有忽略任何重要的事情,我猜你不能相信你的代码是内联的。
【讨论】:
以上是关于在基类体内声明但通过派生类调用的函数的内联的主要内容,如果未能解决你的问题,请参考以下文章
警告: deleting object of polymorphic class type which has non_virtual destructor