【问题标题】:inline function members inside a class类内的内联函数成员
【发布时间】:2023-03-02 22:49:01
【问题描述】:

我知道,当函数定义对于性能而言很小并且可以节省编译时间时,将函数(普通函数而不是类中的方法)声明为内联是一种很好的做法。但是类中的内联方法怎么样 我不明白类中内联方法的概念?如何定义它们以及它们是如何工作的。

【问题讨论】:

  • “当函数定义对性能来说很小并且可以节省编译时间时,这是一个很好的做法” - 你从哪里读到的?
  • @OliCharlesworth :我的意思是如果函数包含一个或两个语句,那么将这个函数声明为内联将节省编译对定义所做的跳转时间,特别是如果这个函数被调用了很多次.
  • 请记住,由于编译器会在每个调用站点为内联函数生成代码,因此您可能没有帮助您的编译时间。过多的内联会降低编译时间并增加可执行文件的大小。
  • 只是一个澄清。内联声明不会节省编译时间。它以牺牲大小为代价节省了代码执行期间的时间。假设您放入函数中的代码需要 500 字节。如果没有内联,该函数使用 500 字节,但 cpu 将“浪费”时间用于函数的“跳转”。使用内联代码,每次调用将使用 500 字节,但速度更快。基本上,内联建议编译器更喜欢速度而不是大小。在执行时间很关键(即中断)的嵌入式环境中非常有用
  • 以下链接是来自 IBM 的简短但非常好的解释。 ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/…

标签: c++ class methods


【解决方案1】:

在类中将函数/过程指定为inline 是在向编译器暗示,与其创建代码来调用函数和传递参数,不如将函数的内容放在调用点。

当无需传递参数即可更高效地执行函数时,它可以提高编译后的二进制文件的性能。这也可能会损害性能,因为在每个调用位置重复函数中的代码可能会导致膨胀,从而降低您的代码在更快的高速缓存中找到的可能性。

【讨论】:

    【解决方案2】:

    但是类中的内联方法呢?

    内联函数的两种语法(使用显式 inline 并在类定义中定义成员函数)仅提供有关编译器内联的提示。从性能的角度来看,它们是相等的。

    如果在类声明中定义一个成员函数,后者的可读性应该是你主要关心的:用多行实现细节乱扔类接口真的很痛苦。因此,如果您的成员函数不止一个语句,请避免这样做:return stuff 或简单转发应该可以,但通常不会超过这个。

    class MyClass
    {
    public:
        int f() const { return m_i; }
        int g() const;
    
    private:
        int m_i;
    };
    
    inline int MyClass::g() const
    {
        return m_i;
    }
    
    // both member-functions behave equally (except for naming)
    

    【讨论】:

    • 是声明,g()的定义必须和main()函数在同一个文件中。或者可以只写函数 g() 的声明和另一个文件中的定义。
    • 定义可以放在单独的文件中,但它需要与调用@的代码在同一个翻译单元中987654324@。这实际上意味着该定义应包含在包含该调用的源文件中。
    • 这是否意味着类定义中的函数定义被自动视为内联?如果不是这样,为什么可以在不同的文件中多次定义同一个类(具有相同的函数)而不破坏函数的单一定义规则?
    • @Hal 是的,确实如此
    • '(命名除外)'是编译后函数的命名吗?
    【解决方案3】:

    有两个选项可以提供给编译器来内联类函数:

    (1)在类的声明中定义一个函数(在头文件中)

    class Human {
    
    public:
    
        Human(const char* name);
        Human();
    
        // is implicit inline
        void lookAt(const char* name) const {
            std::cout << "I'm looking at " << name << std::endl;
    
        }
    
    private:
        char _name[30]; 
    
    }; 
    

    (2)在函数定义中显式使用inline关键字(在头文件中)

        // is explicit inline 
        inline void lookAt(const char* name) const {
            std::cout << "I'm looking at " << name << std::endl;
    
        }
    

    【讨论】:

    • 您不能将inline 方法放在.cpp 文件中。它仍然必须放在标题中。
    • 是的,你是对的。如果我将内联方法定义放在 .cpp 文件中,我将从链接器收到“未解决的外部”错误。因此,无论是显式还是隐式,内联函数都必须在标题中。
    • 不过有一个例外:private 内联函数只能在 cpp 文件中使用可以在那里定义...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2014-04-02
    • 2011-04-28
    • 2013-11-29
    • 2012-09-23
    相关资源
    最近更新 更多