【问题标题】:how do I initialize a const int member in class constructor如何在类构造函数中初始化 const int 成员
【发布时间】:2014-05-01 11:22:34
【问题描述】:

当我构造一个 TestCase 时,我会初始化我的类 TestCase 的一个 const int 成员 (numGrids)。它需要是 const (我认为),因为它定义了该类的另一个数组成员的元素,我也想在创建 TestCase 时对其进行初始化。代码如下:

///////////////////////////////////////// ////////////////////////////// //TestCase.h 类测试用例 { 受保护: 常量 int numGrids; 网格网格[numGrids]; 上市: 测试用例(常量 int); }; ///////////////////////////////////////// ////////////////////////////// //TestCases.cpp TestCase::TestCase(const int numGridsSpec) { numGrids = numGridsSpec; 网格网格[numGrids]; }

我似乎无法初始化我班级的 const 成员。我需要该成员保持不变,因为它定义了网格的数组大小。我收到以下错误:

[ 12%] 构建 CXX 对象源/CMakeFiles/GridRefinementStudy.dir/TestCase.cpp.o 在 /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:16:0 中包含的文件中: /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.h:5:12:错误:非静态数据成员“TestCase::numGrids”的使用无效 /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.h:6:14:错误:来自这个位置 /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.h:6:22:错误:数组绑定在“]”标记之前不是整数常量 /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:在构造函数“TestCase::TestCase(int)”中: /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:25:1: 错误:未初始化的成员 ‘TestCase::numGrids’ 与 ‘const’ 类型 ‘const int’ [-fpermissive] /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:28:13:错误:分配只读成员‘TestCase::numGrids’ /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:29:21:错误:没有匹配函数调用‘Grid::Grid()’ /home/omar/Documents/Programming/C++/FCFD/Current/sources/TestCase.cpp:29:21:注意:候选人是: /home/omar/Documents/Programming/C++/FCFD/Current/sources/Grid.h:13:2: 注意:Grid::Grid(int, int, double, double) /home/omar/Documents/Programming/C++/FCFD/Current/sources/Grid.h:13:2:注意:候选人需要 4 个参数,提供 0 个 /home/omar/Documents/Programming/C++/FCFD/Current/sources/Grid.h:1:7:注意:Grid::Grid(const Grid&) /home/omar/Documents/Programming/C++/FCFD/Current/sources/Grid.h:1:7:注意:候选人需要 1 个参数,提供 0 make[2]: *** [sources/CMakeFiles/GridRefinementStudy.dir/TestCase.cpp.o] 错误 1 make[1]: *** [sources/CMakeFiles/GridRefinementStudy.dir/all] 错误 2 make: *** [全部] 错误 2

【问题讨论】:

  • 数组大小必须是编译时常量表达式。您要么想要std::vectorstd::array
  • 你需要初始化列表来初始化常量。我建议将数组更改为 std::vector。
  • 请正确编辑您的代码!我开始了,剩下的留给你...
  • @KerrekSB 他还需要std::array 的编译时间常数。
  • 一个(可能是丑陋的)解决方案是将size_t numGrids 作为模板参数传递,因为 OP 认为数组的大小在编译时是已知的。

标签: c++ constructor initialization constants


【解决方案1】:

你不能这样做。数组的大小应在编译时知道。实际上,您正在尝试获取可变长度数组。 C++ 没有这样的特性。 考虑到如果两个对象的数组大小不同,那么定义它们的类是不同的类型。它们具有不同的数据成员,即具有不同大小的数组。对于该类的每个对象,该类的大小应相同。 如果编译器支持,我建议使用标准容器std::dynarraystd::vector

另一方面,您可以将您的类定义为模板类。例如

template <size_t numGrids>
class TestCase {

protected:


Grid meshes[numGrids];

//...

甚至是

template <size_t numGrids>
class TestCase {

protected:


std::array<Grid, numGrids> meshes;

//...

我认为在你的情况下使用模板类是最好的方法。

【讨论】:

  • 好的,但是当我在 main 中创建一个 TestCase 并为其指定一个 const 值时,数组大小在编译时是否未知。该类的大小取决于我的初始化方式。我应该提到我是一个业余程序员。
  • @user3592458 我认为这种方法没有意义,因为据我了解,您想定义具有不同数组大小的类的对象。
  • @user3592458 如果不同对象的数组大小不同,那么定义它们的类也是不同的类型。所以我建议使用模板类。
【解决方案2】:

在 C++11 之前,有四种初始化成员的方法:

  • 如果成员是static, const 并且具有整数类型, 可以直接在类定义中初始化。在这个 在这种情况下,该成员是“整数常量表达式”,并且可以是 在编译器需要的任何地方使用(例如数组维度, 模板参数等)。

  • 如果成员是static,它必须在其初始化 定义。如果成员也是const,则为常量 翻译单元中的表达式,其中包含 定义,在定义之后。

  • 可以在初始化列表中初始化任何成员,并且 通常,所有都应该是(但也有例外)。非静态 const 成员 必须 在这里初始化(但非静态 const 成员是 not 常量表达式,不能用作 这样)。

  • 最后,非常量成员可以在 构造函数体。形式上,这是赋值,而不是初始化,如果 成员类型有一个用户定义的构造函数,它仍然是 初始化(使用默认构造函数)在 初始化列表。对于原始类型,成员保持 如果未在初始化列表中提及,则未初始化, 直到它被第一次分配。

在您的情况下,您似乎想要一个大小为 由构造函数的参数定义。这不是 可能的;数组的大小必须是整数常量 表达。如果大小应该始终相同,那么您可以 使用静态 const int 来定义它:

class TestClass
{
    static int const numGrids = 25;
    Grid meshes[numGrids];
    //  ...
};

否则,您将不得不使用:

class TestClass
{
    std::vector<Grid> meshes;
public:
    TestClass( int size ) : meshes( size ) {}
};

无论如何,这可能是更好的解决方案。

【讨论】:

    【解决方案3】:

    首先由于类声明中numGrids是const,所以只能通过初始化列表来初始化。

    TestCase::TestCase(const int numGridsSpec)
      :numGrids(numGridsSpec)   // this is the initialization list
    {
    ... 
    }
    

    这仅仅是因为一个常量变量只能设置一次值,之后不能“合法”修改,编译器通常不允许你继续进行,以避免在这种情况下出现意外后果。

    【讨论】:

      【解决方案4】:

      您的代码中有错误。数组大小是动态的(变量)。您不能在编译时使用变量来声明数组大小。使用一些具有实际价值的常量。

      回答你的问题

      初始化器列表用于为 const 初始化数据。如下。

      class TestCase {
      
          protected:
              const int numGrids;    
      
          public:
      
              TestCase(const int x) : numGrids(x)
              {
              }
      };
      

      解决您的问题

      class TestCase {
      
          protected:
      
              const int numGrids;
              Grid* pMeshes;
      
          public:
      
              TestCase(const int x) : numGrids(x)
              {
                  pMeshes = new Grid[x];
              }
      
              ~TestCase() : numGrids(x)
              {
                  delete []pMeshes; // release allocated memory in destructor
              }
      };
      
      int main(int argc, char* argv[])
      {
          TestCase t(10);
          return 0;
      }
      

      【讨论】:

      • 好的,我尝试按如下方式编辑我的 .cpp 文件: // 稳定 TestCase 的构造函数 TestCase::TestCase(const int numGridsSpec) :numGrids(numGridsSpec) { cout
      【解决方案5】:

      如果你的编译器支持 c++11,你可以这样做:

      class TestCase
      
      {
      
      protected:
      
          const int numGrids = 25;
      
          Grid meshes[numGrids];
      
      public:
      
          TestCase(const int);
      
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-04
        • 2016-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多