Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将常量局部变量定义为静态变量(c+;+;)的利弊是什么?_C++_C++11_C++14_C++17 - Fatal编程技术网

C++ 将常量局部变量定义为静态变量(c+;+;)的利弊是什么?

C++ 将常量局部变量定义为静态变量(c+;+;)的利弊是什么?,c++,c++11,c++14,c++17,C++,C++11,C++14,C++17,将常量局部变量定义为静态变量的利弊是什么? 将索引,zOrder,isLooping定义为静态的开销是多少。这样做有什么好处吗?一般情况下,如果在函数中声明一个静态变量,那么它将在首次使用时初始化。为了实现此行为,编译器将创建另一个布尔类型的全局静态变量。初始化相关静态变量后,它将首先设置为false,然后设置为true 在您的情况下,没有必要将任何变量声明为静态变量。是的,在函数中使用静态变量时会有一点开销,因为每次程序执行该函数时,都必须检查这些静态变量是否已初始化。让我们从简单的变量开始

将常量局部变量定义为静态变量的利弊是什么?
索引
zOrder
isLooping
定义为
静态
的开销是多少。这样做有什么好处吗?

一般情况下,如果在函数中声明一个静态变量,那么它将在首次使用时初始化。为了实现此行为,编译器将创建另一个布尔类型的全局静态变量。初始化相关静态变量后,它将首先设置为
false
,然后设置为
true


在您的情况下,没有必要将任何变量声明为静态变量。

是的,在函数中使用静态变量时会有一点开销,因为每次程序执行该函数时,都必须检查这些静态变量是否已初始化。

让我们从简单的变量开始

常数:

const没有给你任何好处,它给你的唯一好处是变量在它的生命周期内不能被改变。这很有趣,因为:

正确性

如果想要清楚地显示变量的内容,请使用const明确表示变量不会/不能更改

你可能会想,为什么我不使用定义。好的,define将使编译器替换它来修复值,在某些情况下,它不像字符串或对象那样具有优势

保护

如果其他人使用你的函数,你要明确这个变量是可以更改的,你要保护它的值

静态:

静态会给您带来开销,因为在第一次创建变量之后,它将在程序的生命周期中存在,其优点正是如此。当变量为create时,给它一个值。因为在那之后它仍然活着,无论发生什么,它都不能再次获得值,因为它是第一次

让我们看一个类的例子

假设您希望一个类管理一个int的加法,并且该int需要累积该加法,包括创建和/或销毁该类的新对象:

void Animation::playAnimation() const
{
    static const int index = 0;
    const std::string& animationFileName = m_animationContainer.getAnimationName(index);
    static const int zOrder = -1;
    static bool isLooping = false;

    AnimationBank::play(animationFileName,
                        zOrder,
                        isLooping);
}
#包括
使用名称空间std;
阶级阶级{
公众:
无效打印_iVar();
void Add_iVar();
私人:
静态积分;
};
int classacit::iVar=10//iVar=10
void classacit::Print_iVar(){//Show iVar
无法添加_iVar();//iVar=iVar+1
oC1->Print_iVar();//Print iVar
删除oC1;//再见我们所做的…你确定吗?
ClassAcInt*oC2=newclassacint();//iVar=10?确定吗?
oC2->Print_iVar();//Print iVar…真是个黑客!!!!
oC2->Add_iVar();//iVar=iVar+1
oC2->Print_iVar();//天哪。。。
删除oC2;
}
你可以认为结果会是: 10 11 10 十一,

但“令人惊讶”的结果是: 10 11 11 十二,


关键是线路静态int iVar;和int classacit::iVar=10;。试着抑制静态单词,看看会发生什么:)

在优化下?可能与它们是否是静态的无关。没有运行时开销。静态变量存储在进程地址空间的数据部分。有什么好处吗?值得一试吗write@FaceBro因此,存在潜在的开销。从内存加载到寄存器。@FaceBro这些变量可能直接存储在寄存器中,而不必存储在堆栈上。当使用静态变量时,它们必须在运行时加载到寄存器。这是否重要完全取决于您想要实现什么,取决于您的cpu和其他数千个因素。可能没关系。还是我遗漏了什么?我修改了问题如下:将常量局部变量定义为静态变量的优缺点是什么?将
索引
zOrder
isLooping
定义为
静态
的开销是多少。这样做有什么好处吗?标准只要求在第一次使用前对块(功能体是块的一种类型)本地的静态进行初始化,这通常相当于在第一次输入块时或之前。没有任何东西可以阻止它提前初始化(例如在程序启动时),这意味着不需要使用另一个静态标志(但不是禁止)。@Peter you's Error,标准6.7声明语句[stmt.dcl]:“使用静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)动态初始化块作用域变量”在控件第一次通过其声明时执行;这样的变量在初始化完成时被视为已初始化……”这只是C++11及更高版本的真实情况。在早期的C++标准中,这是不正确的。这个帖子被标记为C++ 11和C++ 14,所以我想没有必要讨论老的标准。我已经修改了如下问题:什么是定义静态局部变量的利弊?将
索引
zOrder
isLooping
定义为
静态
的开销是多少。这样做有什么好处吗?它们是不同的,
静态变量
将在函数退出后保留,但
局部变量
将被销毁(您可以搜索自动变量),
常量局部变量
仅向其添加
常量
属性。您是指
全局变量
#include <iostream>
using namespace std;
class ClassAcInt {
      public:
             void Print_iVar();
             void Add_iVar();
      private:
             static int iVar;
};

int ClassAcInt::iVar = 10;           //iVar = 10

void ClassAcInt::Print_iVar() {      //Show iVar
     cout << iVar << '\n';
}

void ClassAcInt::Add_iVar() {        //Add 1 to iVar
     iVar++;
}

int main () {
    ClassAcInt* oC1 = new ClassAcInt();     //iVar = 10
    oC1->Print_iVar();                      //print iVar
    oC1->Add_iVar();                        //iVar = iVar + 1
    oC1->Print_iVar();                      //Print iVar
    delete oC1;                             //Bye what we did... Are you sure?

    ClassAcInt* oC2 = new ClassAcInt();     //iVar = 10? Are you sure?
    oC2->Print_iVar();                      //Print iVar.... What a hack!!!!
    oC2->Add_iVar();                        //iVar = iVAr + 1
    oC2->Print_iVar();                      //omgosh...
    delete oC2;
}