【问题标题】:How to freeze a variable since it first assigned?自首次分配以来如何冻结变量?
【发布时间】:2017-12-22 22:41:17
【问题描述】:

请在这个问题中假设 gcc 7.2.1 的版本

我想声明一个行为类似于 const 的全局变量,但是在程序执行之前无法检测到初始化它的值。换句话说,目标变量将在第一次分配后重新分配。

这个概念的一个丑陋的方法如下:

#include<iostream>

int numberOfPeople; //Do not re-assign it after it first assign

int main(){
  std::cin >> numberOfPeople; // Do not re-assign numberOfPeople since then !!!
  // Following of codes omitted.
}

如您所见,这是一种非常丑陋的方法,编译器无法检查。我想知道 C++ 中是否有一种表示法可以冻结变量,因为它第一次分配。

所以我可以这样写代码:

#include<iostream>

magic_notation int numberOfPeople;

int main(){
  std::cin >> numberOfPeople; // Allowed as it's first assign.
  // Median codes omitted.
  numberOfPeople = 60. //Disallowed and will get an error message from compiler!
  // Following codes omitted.
}

在上面的 c++ 代码中,有没有可以像 magic_notation 这样使用的符号?

【问题讨论】:

  • 使其成为控制访问的类的成员。
  • @neil-butterworth 感谢您的回复。但是,你能给我一个示例代码吗?
  • 我想你正在寻找这个:stackoverflow.com/questions/35800643/…
  • @EIjay 感谢您的回复。这是相似的。但是,我想找到一个基于语法的解决方案。
  • @TJM • 我认为您不会得到您所要求的编译时错误。它可以默默地忽略后续分配,或者在后续分配中抛出异常。

标签: c++


【解决方案1】:

最好的方法是创建一个具有公共const 成员变量的类,该变量在构造函数中被初始化:

struct InitInfo {
    const int numberOfPeople;
    InitInfo() numberOfPeople(getNumberOfPeople()) {
    }
private:
    static int getNumberOfPeople() {
        int res;
        cin >> res;
        return res;
    }
};
InitInfo initInfo;

现在可以按如下方式使用成员变量:

int main() {
    cout << initInfo.numberOfPeople << endl;
}

您也可以使用相同的方法来初始化全局变量。

static int getNumberOfPeople() {
    int res;
    cin >> res;
    return res;
}
const int numberOfPeople = getNumberOfPeople();
int main() {
    cout << numberOfPeople << endl;
    numberOfPeople += 10; // <<== This triggers an error
}

【讨论】:

  • 感谢您的回复,所以const int numberOfPeople = getNumberOfPeople()是在main()的第一行之前执行的?
  • @TJM 是的,在输入main之前会初始化。
【解决方案2】:

您可以使用的一种方法是将变量包装为函数中的静态变量。在其余代码中使用函数而不是变量。

#include <iostream>

int readFromStdin()
{
   int n;
   cin >> n;
   return n;
}

// Wrap it arund in a function.
// int numberOfPeople; //Do not re-assign it after it first assign

int getNumberOfPeople()
{
   // Initialize by reading from stdin.
   static int numberOfPeople = readFromStdin();
   returnn numberOfPeople;
}

int main(){

   // Use the function instead of the variable.
   getNumberOfPeople();
}

【讨论】:

  • 感谢您的回复,它看起来像单例模式。但是,有没有更简单的方法来做到这一点?
  • @TJM 不,没有。没有像 const 这样的修饰符,您可以简单地将其添加到变量声明中。也许你可以找到一个提供write_once 类模板或其他东西的库,这样你就可以编写write_once&lt;int&gt; numberOfPeople;,它会按照你的意图工作。
  • @Justin ...好吧,从技术上讲,您可以在分配时抛弃 const-ness。值得畏缩,我知道。
  • @Dúthomhas,这从一开始就是未定义的行为。
  • 呃,写入到 const 的东西是未定义的行为,如果我们对数据一无所知,只知道它的 const-on-arrival。 OP 正在询问特别已知为非常量但以 const 形式呈现给所有人的数据。我同意,这是一根好头发,我不推荐它。
【解决方案3】:

如果你有不同的方法来初始化变量,你可以想出这样的东西:

struct {
    int value() const { return _val; }
    void init(int val) {
        if(!_set) _val = val;
    }
  private:
    int _val;
    bool _set = false;
} numberOfPeople;

现在,使用该变量的每个人都应该在使用它之前调用init 以确保它已被初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 2010-12-27
    • 2018-04-13
    相关资源
    最近更新 更多