C++ C+中的类开销+;

C++ C+中的类开销+;,c++,performance,class,oop,C++,Performance,Class,Oop,我有一门课,例如: class Vehicle { public: Vehicle(int handle); // Methods that use the handle e.g.: Color getColor() { return VEHICLE::GET_COLOR(handle); } protected: int handle; }; 我不知道这个例子对您是否有意义,但我围绕这些句柄构建了几个包装器类,以获得更OOP

我有一门课,例如:

class Vehicle {
  public:
    Vehicle(int handle);

    // Methods that use the handle e.g.:
    Color getColor() {
        return VEHICLE::GET_COLOR(handle);
    }

  protected:
    int handle;
};
我不知道这个例子对您是否有意义,但我围绕这些句柄构建了几个包装器类,以获得更OOP风格的编码


所以我现在的问题是,当我传递一个
Vehicle
对象而不是仅仅将Vehicle句柄传递给其他方法时,会有多少开销?

如果将类拆分为头文件和源文件,并在其他编译单元中使用它,那么由于调用构造函数,会有很小的开销

要解决这个问题,必须将构造函数的定义放在头文件中,以便编译器可以内联它

您可以通过更改类声明来实现这一点:

class Vehicle {
public:
    Vehicle(int handle)
     : handle(handle)
    {
    }
...
或者将定义放入headerfile中,并使用
inline
关键字对其进行修饰

class Vehicle {
public:
    Vehicle(int handle);
...
}

inline Vehicle::Vehicle(int handle)
 : handle(handle)
{
}
请注意,没有保证您的函数将被内联,但可能每个主要的编译器都能做到这一点

还要注意,构造函数中的额外工作,例如
handle-1
,也很可能导致开销


如果您的类是多态的或更大的,可能会有额外的开销。

优化编译器将确保这样简单的调用转发不会有开销。核心类(由包装器使用)理想情况下应该在同一个模块(DLL/SO)中,否则链接器/优化器可能没有什么帮助


然而,对于围绕核心类的这种精简包装,即使在共享库场景中,编译器也会简单地调用核心方法,从而从调用站点中消除包装类方法。

“由于调用构造函数,可能会有少量开销”。我希望LTO能够插入并内联对简单构造函数的任何调用,即使它们是在不同的TU中定义的。这并非不可能,您可能会在
句柄中引入开销,因为您需要更具体的数据。记住霍尔的格言:过早优化是万恶之源。使用探查器测量性能,而不是猜测。(其他因素也会起作用,例如您是通过值还是引用传递,实际类有多大,您使用的优化设置等)Knuth:“程序员浪费大量时间考虑或担心其程序中非关键部分的速度,而在考虑调试和维护时,这些提高效率的尝试实际上会产生强烈的负面影响。我们应该忘记小效率,比如说97%的时间:过早优化是万恶之源。然而,我们不应该错过关键的3%的机会。”通过比较编译器为您的平台为每个实现生成的目标代码,您将看到开销。