【问题标题】:set default parameter to a member variable [duplicate]将默认参数设置为成员变量[重复]
【发布时间】:2021-12-29 16:53:49
【问题描述】:

我试图为成员变量设置一个默认参数,它给了我这个错误。

[cquery] invalid use of non-static data member 'num'

代码

#include <iostream>
class Test{
   private:
      int val = 0;
   public:
      void print_num(int num = val){
         std::cout << num << '\n';
      }
}
int main(){
   Test test;
   test.print_num();
   return 0;
}

【问题讨论】:

    标签: c++ class parameters


    【解决方案1】:

    尽管这意味着什么很明显,但你不能。通常的解决方法是提供一个重载(隐式)使用this 来获取成员值。

    【讨论】:

      【解决方案2】:

      为了给类成员设置函数参数的默认值,该成员必须是静态的。

      引用documentation

      默认参数中不允许非静态类成员

      但是,鉴于您的代码示例的上下文,我怀疑这是您想要做的(因为Test 类的每个实例都将指向相同的val。引用docs

      类的静态成员不与类的对象相关联:它们是自变量

      如果您在示例中将 val 设为静态,并且您的代码使用了多个 Test 实例,您可能(并且很可能会)出现一些意外行为。考虑:

      #include <iostream>
      class Test{
         private:
            static int val;
         public:
            void print_num(int num = val){
               std::cout << num << '\n';
            }
            void set_val(int num) {
                val = num;
            }
      }
      int Test::val = 0;
      int main(){
         Test test1;
         test1.set_val(1);
         Test test2;
         test2.set_val(2);
         test1.print_num(); // results in "2"
         return 0;
      }
      

      更好的选择是将指针传递给您的函数,如下所示:

      #include <iostream>
      class Test{
         private:
            int val = 0;
         public:
            void print_num(int* numptr = nullptr){
               int num = (numptr ? *numptr : val);
               std::cout << num << '\n';
            }
      }
      int main(){
         Test test;
         test.print_num();
         return 0;
      }
      

      或者,如 Davis Herring 所述,使用重载:

      #include <iostream>
      class Test{
         private:
            int val = 0;
         public:
            void print_num(int num){
               std::cout << num << '\n';
            }
            void print_num() {
              return print_num(val); // return is irrelevant here, but my preferred coding style
            }
      }
      int main(){
         Test test;
         test.print_num();
         return 0;
      }
      

      编辑以反映评论和示例。

      【讨论】:

      • 为了给函数参数设置默认值,必须在编译时知道该值 Not true.
      • @user4581301:也许更有趣的是,您可以在默认参数规范中调用一个函数,甚至是一个凭空创建新值的函数。但是,这对 OP 帮助不大,因为您无法访问 this,通过它您可以访问 val
      • @JohnZwinck 我认为这是问题所在,但我的标准潜水并没有解释为什么你不能这样做,只是你不能。
      • @user4581301 我认为这是一个更好的例子,可以在运行时评估该值:cpp.sh/5gdzs(尝试从标准输入中输入 42 并查看结果)。
      【解决方案3】:

      您的函数定义实际上并不知道 val 是什么,因为它实际上并不存在于您的类中。编译器实际上正在创建一个函数,其中包含您的类作为参数并将所有这些抽象出来。您需要在函数体内将 num 设置为 val。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-25
        • 1970-01-01
        • 2017-01-02
        • 2011-07-31
        • 2015-09-15
        相关资源
        最近更新 更多