当您多次声明相同的对象/变量(新手)时会发生什么

what happens when you declare the same object/variable more than once (newbie)

本文关键字:新手 什么 变量 声明 对象      更新时间:2023-10-16

这样的事情有什么作用?

static int i;
// wrapped in a big loop
void update_text()
{
    std::stringstream ss; // this gets called again and again
    ++i;
    ss << i;
    text = new_text(ss.str()); // text and new_text are defined elsewhere
    show_text(text); // so is this
}

是否在堆栈中创建具有新地址和所有内容的新 SS 实例? 将 Sprintf 与 char 数组一起使用会更聪明吗?

每次调用该函数时,都会在堆栈上推送一个新的本地std::stringstream ss实例。在函数结束时,此实例将被销毁并从堆栈中弹出。

在任何时候,函数的作用域update_text在其作用域中都不能有多个变量,标识符ss 。因此,在update_text范围内,只有一个ss标识符。

字符数组不会有任何区别。每次调用该函数时,char 数组(如果静态分配(将被推送到堆栈上并在末尾弹出。如果使用动态内存并动态分配字符数组,则每次调用函数时仍会执行 newdelete 语句,并且指向此字符数组的指针仍将被推送并从堆栈中弹出。std::stringstream已经在内部为您处理newdelete

多次声明一个对象将如下所示:

void Function()
{
    int x;
    int x;
}

这将导致编译器错误。

请注意,这是有效的:

void Function()
{
    int x;
    if(true)
    {
        int x;
    }
}

因为这两个变量的作用域不同。第二个x仅存在于该if语句中。因此,编译器可以推断出在该声明之后和该范围内对x的任何引用都指向第二个x。请注意,类型无关紧要,重要的是标识符或"名称"。

小点:你的问题不是关于声明一个对象不止一次,而是遇到一个对象被初始化多次的位置。

所以回答你的真正问题:是的,每次调用函数时,它都会创建新的ss实例(尽管如果从循环调用它,地址实际上可能是相同的,但这对程序员来说真的无关紧要(。

对于您的第二个问题:将sprintf与字符数组一起使用会更聪明吗?好吧,如果你是 c++ 的新手,你应该从中得到的答案是否定的,因为sprintf使用起来比streams更危险(缺乏类型安全,溢出风险(。实际的答案是视情况而定。如果您知道自己在做什么,并且使用stringstreams获得的性能不足以满足您的目的(这种情况应该很少发生(,请使用sprintf。此外,请注意,您可以重用stringstreams,这减少了每次创建新投射的开销(这对于流式传输单个int非常重要(,您还可以查看此类投射的Boost.Lexical_Cast。根据他们的性能部分,对于将int转换为string之类的事情,它应该与sprintf一样快(我自己没有测试过,所以没有保证(,而不会暴露缺乏类型安全(和缓冲区溢出的风险(sprintf。C++11 也有 std::to_string ,它可以在不放弃安全性的情况下进行转换(但是它的灵活性远不如 boost::lexical_cast'(。