如何初始化常量数据成员?

问题描述 投票:0回答:13
#include <iostream>

using namespace std;
class T1
{
  const int t = 100;
  public:
  
  T1()
  {
    cout << "T1 constructor: " << t << endl;
  }
};

当我尝试用 100 初始化

const
数据成员
t
时。但它给了我以下错误:

test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static

如何初始化

const
成员?

c++ constructor initialization constants
13个回答
155
投票

const
变量指定变量是否可修改。每次引用变量时都会使用分配的常量值。程序执行期间无法修改分配的值。

Bjarne Stroustrup 的 解释 简要总结:

类通常在头文件中声明,并且头文件通常包含在许多翻译单元中。然而,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许对需要作为对象存储在内存中的实体进行类内定义,则该规则将被打破。

const
变量必须在类中声明,但不能在类中定义。我们需要在类外部定义 const 变量。

T1() : t( 100 ){}

这里的赋值

t = 100
发生在初始化列表中,远远早于类初始化发生。


65
投票

好吧,你可以做到的

static

static const int t = 100;

或者您可以使用成员初始值设定项:

T1() : t(100)
{
    // Other constructor stuff here
}

44
投票

有几种方法可以初始化类中的 const 成员..

一般来说const成员的定义,也需要变量的初始化..

1)在类内部,如果你想初始化const,语法是这样的

static const int a = 10; //at declaration

2)第二种方式可以是

class A
{
  static const int a; //declaration
};

const int A::a = 10; //defining the static member outside the class

3)如果你不想在声明时初始化,那么另一种方法是通过构造函数,变量需要在初始化列表中初始化(而不是在构造函数体内)。一定是这样的

class A
{
  const int b;
  A(int c) : b(c) {} //const member initialized in initialization list
};

24
投票

如果您不想使类中的

const
数据成员成为静态,您可以使用类的构造函数初始化
const
数据成员。 例如:

class Example{
      const int x;
    public:
      Example(int n);
};

Example::Example(int n):x(n){
}

如果类中有多个

const
数据成员,您可以使用以下语法来初始化成员:

Example::Example(int n, int z):x(n),someOtherConstVariable(z){}

14
投票
  1. 您可以升级编译器以支持 C++11,您的代码将完美运行。

  2. 在构造函数中使用初始化列表。

    T1() : t( 100 )
    {
    }
    

9
投票

另一个解决方案是

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

所以 t 初始化为 100 并且不能更改,并且是私有的。


3
投票

如果成员是数组,它会比正常情况稍微复杂一点:

class C
{
    static const int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

int* a = new int[N];
// fill a

class C {
  const std::vector<int> v;
public:
  C():v(a, a+N) {}
};

2
投票

另一种可能的方式是命名空间:

#include <iostream>

namespace mySpace {
   static const int T = 100; 
}

using namespace std;

class T1
{
   public:
   T1()
   {
       cout << "T1 constructor: " << mySpace::T << endl;
   }
};

缺点是其他类如果包含头文件也可以使用常量。


1
投票

这才是正确的做法。你可以试试这个代码。

#include <iostream>

using namespace std;

class T1 {
    const int t;

    public:
        T1():t(100) {
            cout << "T1 constructor: " << t << endl;
        }
};

int main() {
    T1 obj;
    return 0;
}

如果您使用

C++10 Compiler or below
,则无法在声明时初始化 cons 成员。所以这里必须让构造函数来初始化const数据成员。还必须使用初始化列表
T1():t(100)
来即时获取内存。


1
投票

在 C++ 中,不能在声明时直接初始化任何变量。 为此,我们必须使用构造函数的概念。
看这个例子:-

#include <iostream>

using namespace std;

class A
{
    public:
  const int x;  
  
  A():x(0) //initializing the value of x to 0
  {
      //constructor
  }
};

int main()
{
    A a; //creating object
   cout << "Value of x:- " <<a.x<<endl; 
   
   return 0;
}

希望对您有帮助! 请点赞😉


0
投票

可以添加

static
来实现该类成员变量的初始化。

static const int i = 100;

但是,在类声明内部使用这并不总是一个好的做法,因为从该类实例化的所有对象将共享相同的静态变量,该变量存储在实例化对象的范围内存之外的内部内存中。


0
投票

到 2023 年,您的示例现在可以编译,没有任何错误。无需使用初始化列表或将变量设为静态。我编译并运行了与您相同的代码:

g++ -std=c++11 -Wall -Wpedantic -Wextra -Werror -Wuninitialized -Wsuggest-override test.cpp

我用:

~$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

0
投票

const 成员如何初始化取决于该成员是静态还是非静态。如果成员是静态的,则 const 成员是所有类实例共享的不可变值。

如果成员是非静态的,则 const 成员是不可变的,但可能会随着每次实例化而变化。

#include <iostream>

int GetRandomNum()
{
    int retVal;
    std::cout << "Enter a number to initialize A: "; 
    std::cin >> retVal; 
    return retVal; 
}

struct A
{
    static const int member1 = 1;
    static const int member2;

    const int member3 = GetRandomNum(); // Dynamically assigned
    const int member4; // Uninitialized, dynamically assigned
    const int member5 = 0; // Literal
    const int member6 = 6;

    A() : member4(GetRandomNum()), member5(5) // member5 is redefined!
    {
    }

    void PrintMember1() { std::cout << "member1: " << member1 << "\n"; }
    void PrintMember2() { std::cout << "member2: " << member2 << "\n"; }
    void PrintMember3() { std::cout << "member3: " << member3 << "\n"; }
    void PrintMember4() { std::cout << "member4: " << member4 << "\n"; }
    void PrintMember5() { std::cout << "member5: " << member5 << "\n"; }
    void PrintMember6() { std::cout << "member6: " << member6 << "\n"; }
};

const int A::member2 = 2; 

int main()
{
    // Do twice. 
    for (int i = 1; i <= 2; i++)
    {
        A a1;
        a1.PrintMember1();
        a1.PrintMember2();
        a1.PrintMember3();
        a1.PrintMember4();
        a1.PrintMember5();
        a1.PrintMember6();
    }
    
    cout << "Exiting ...\n";
    return 0;
}

输入/输出:

Enter a number to initialize A: **100**
Enter a number to initialize A: **200**
member1: 1
member2: 2
member3: 100
member4: 200
member5: 5
member6: 6
Enter a number to initialize A: **300**
Enter a number to initialize A: **400**
member1: 1
member2: 2
member3: 300
member4: 400
member5: 5
member6: 6
© www.soinside.com 2019 - 2024. All rights reserved.