什么更好用,为什么?

What's better to use and why?

本文关键字:为什么 更好 什么      更新时间:2023-10-16
class MyClass {
    private:
        unsigned int currentTimeMS;
    public:
        void update() {
            currentTimeMS = getTimeMS();
            // ...
        }
};
class MyClass {
    public:
        void update() {
            unsigned int currentTimeMS = getTimeMS();
            // ...
        }
};

update(( 在主游戏循环中调用,因此在第二种情况下,我们得到了大量的分配操作(无符号的 int currentTimeMS(。在第一种情况下,我们只得到一个分配,并在之前使用该分配的变量。使用哪种代码更好,为什么?

我推荐第二个变体,因为它是无状态的,变量的范围更小。仅当您确实遇到性能问题时才使用第一个,我认为这不太可能。

如果以后不修改变量值,则还应考虑使其const,以便在代码中表达此意图,并为编译器提供其他优化选项。

这取决于您的需求。如果currentTimeMS只是暂时需要update(),那么一定要在那里声明。(在您的情况下,#option2(

但是,如果类的实例需要它的值(即在其他方法中使用(,那么您应该将其声明为字段(在您的情况下,#option1(。

在第一个示例中,您将保存此类对象的状态。在第二个中,你不是,所以当前时间将丢失,即时更新((被调用。

真正由您决定您需要哪一个。

第一种情况是定义成员变量,第二种情况是局部变量。基础类的东西。 私有成员变量可用于该类中的任何函数(方法(。 局部变量仅在声明它的函数中可用。

使用哪种代码更好,为什么?

首先,引用的代码充其量只是一个微小的微优化。除非必要,否则不要担心这些事情。

事实上,这很可能是一种优化。有时在堆栈上分配自动变量。堆栈分配非常快(有时甚至免费(。无需担心。其他时候,编译器可能会在寄存器中放置一个小的自动变量,例如此处使用的unsigned int。没有任何分配。

将其与使变量成为类的数据成员进行比较,并且仅用于避免该分配。访问该变量涉及通过this指针。指针取消引用的成本可能远远超过向指针添加偏移量的成本。取消引用可能会导致缓存未命中。更糟糕的是,每次引用变量时都可能执行这种取消引用。


也就是说,有时最好仅出于避免各种成员函数中的自动变量而创建数据成员。声明为局部自动变量的大型数组可能会导致堆栈溢出。但是请注意,将double big_array[2000][2000]作为 MyClass 的数据成员很可能使无法将类型MyClass变量声明为某个函数中的局部自动变量。

对于将大型数组放在堆栈上所产生的问题,标准解决方案是将它们分配到堆上。这导致了另一个地方,创建数据成员以避免局部变量可能是有益的。虽然堆栈分配非常快,但堆分配(例如,new(非常慢。重复调用的成员函数可以通过使自动变量std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) MyClass 的数据成员而受益。

请注意,以上都不适用于问题中的示例代码。另请注意,最后一个问题(使堆分配的变量成为数据成员以避免重复分配和解除分配(意味着代码必须通过this指针才能访问该内存。在紧凑的代码中,我有时被迫创建一个本地自动指针变量(如 double* local_pointer = this->some_pointer_member(,以避免重复遍历this