BЈо*_*вић 3 c++ pimpl-idiom inline
考虑下一个简单的例子:
标题:
// a.hpp
#ifndef A_HPP
#define A_HPP
#include <memory>
class A
{
public:
A();
int foo();
private:
struct Imp;
std::auto_ptr< Imp > pimpl;
};
#endif // A_HPP
Run Code Online (Sandbox Code Playgroud)
实施:
// a.cpp
#include "a.hpp"
struct A::Imp
{
int foo()
{
// do something and return the result
}
};
A::A() : pimpl( new Imp )
{}
int A::foo()
{
return pimpl->foo();
}
Run Code Online (Sandbox Code Playgroud)
主要的 :
// main.cpp
#include "header.hpp"
int main()
{
A a;
return a.foo();
}
Run Code Online (Sandbox Code Playgroud)
问题是:
方法是否A::Imp::foo会被内联到A::foo?
它取决于实现该方法中的内容吗?
PS我正在使用gcc(4.3.0如果重要的话).
编辑
我想我没解释得很好.我的意思是这个.如果我使用最大优化级别,是否// do something and return the result会被放置在A::foo()或A::Imp::foo()?
没有优化,我发现这没有完成(the pimpl->foo()仍然被称为).
我知道A :: foo()永远不会在main()中内联,但这不是我要问的.
Herb Sutter曾做过一篇关于内联的伟大文章.
要问的第一个问题是:何时可以进行内联?
在C++中:
两次,机制都类似:如果编译器/链接器知道该方法的实现,它可能决定复制/粘贴实现而不是发出调用.这个决定是基于复杂的启发式方法,我只知道它们存在,而不是它们的含义.
因此关键点是了解实现位.
所以这里:是的,pimpl->foo()可以在内部调用内容A::foo.它取决于编译器和编译选项.
对于gcc/clang,如果A::Impl::foo足够小,可以从O1开始优化(除非你通过-fno-inline).