C++类中数据成员初始化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++类中数据成员初始化相关的知识,希望对你有一定的参考价值。

#include<iostream.h>
    class OBJ1
    
     public:
      OBJ1() cout <<"OBJ1\n";
    ;
    class OBJ2
    
     public:
      OBJ2() cout <<"OBJ2\n";
    ;
    class Base1
    
     public:
      Base1() cout <<"Base1\n";
    ;
    class Base2
    
     public:
      Base2() cout <<"Base2\n";
    ;
    class Base3
    
     public:
      Base3() cout <<"Base3\n";
    ;
    class Base4
    
     public:
      Base4() cout <<"Base4\n";
    ;
    class Derived :public Base1, virtual public Base2,
        public Base3, virtual public Base4
    
     public:
      Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1()
     
      cout <<"Derived ok.\n";
     
     protected:
      OBJ1 obj1;
      OBJ2 obj2;
    ;
    void main()
    
     Derived aa;
     cout <<"This is ok.\n";
    

----------------------------------------------------------------------------------------------------

   其中 class Derived 的

Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1()

..........

这个成员初始化是怎么回事?()内无数据这样是给多少初值?Base4()这样的Base4不是类的一个函数成员么?它本身并没有形参,为什么这里给它初始化初值?哪个变量的初值?

你的Base4类里面没有成员变量,该构造函数就没有给什么变量赋初值,只是执行了一个动作,
cout <<"Base4\n";
参考技术A 这个你写的很不对呢,看看书上的例子吧,看书后会很有帮助的追问

……这个是清华出版社的教材的一个例子额。。。。。只不过这个构造函数数据成员初始化比较特殊一点。。。。我想知道到底初始化的值给哪个变量了…

追答

什么都没有没有初始化,没有成员变量啊,,,只是输出函数操作而已

参考技术B Base4()是构造函数,你需要好好看看C++基础知识追问

我知道是构造函数,而且是一个Base4类的公共成员函数,我想知道为什么给它初值?直接在冒号后进行数据初始化Base4(),那么()是给多少值?把0给Base4?而Base4是一个构造成员函数,这个初值放到哪里了?

追答

Base4内部没有看到任何成员变量,无需初始化赋值

参考技术C 同问

在 C++ 类中使用复杂函数初始化 const 成员

【中文标题】在 C++ 类中使用复杂函数初始化 const 成员【英文标题】:Initialize const members using complex function in C++ class 【发布时间】:2014-08-03 12:46:24 【问题描述】:

我有一个适用于 3d 网格的程序。这个网格有自己的类对象 Grid,看起来像这样(简化版):

class Grid

  public:
    Grid()  readDataFromInputFile(); 
  private:
    void readDataFromInputFile() ... // this function reads the values for i, j, k from disk
    int i; int j; int k;
;

我现在想做的是能够将变量 i、j 和 k 设置为 const int,以避免在其他函数中意外地将它们弄乱。然而,我不能轻易地将它们设置在成员初始化器列表中,因为它们必须从文件中读取。我一直在浏览现有的讨论,但找不到关于这个问题的准确讨论。

是否有解决方案可以将它们设置为 const,并且仍然可以使用复杂的函数来检索数据?在我的实际应用中,当然要读取的变量要多得多,初始化后不允许更改。

【问题讨论】:

糟糕,readDataFromInput 也是一个成员函数,我只是为了说明我使用了一个复杂的函数,包括从磁盘读取 .ini 文件中的多个变量的 IO。 我已经编辑了帖子,使其更加清晰。 看起来我正确理解了您的意思,即使代码没有多大意义。 一种选择是将变量设为i_j_k_ 或其他不太可能的名称,并在构造函数中将类成员int const &amp;i 绑定到i_ (这可以在 i_ 赋值之前完成) “有没有办法可以将它们设置为 const...?” - 不,不是这种设计。 const 表示它们必须在任何使用或访问使用之前进行初始化,包括构造函数主体、调用任何非静态成员函数等。像引用成员(const与否),它们必须出现在构造函数的字段初始值设定项列表中。没有什么可以逃避的。这就是语言的工作原理。马努的评估是正确的。 【参考方案1】:

不要打破一个责任原则:Grid 不应该负责从文件中加载自己,这是另一个组件的责任(例如简单的加载功能):

class Grid

public:
    Grid( int ii , int jj , int kk ) : i ii  , j jj  , k kk 
private:
    const int i , j , k;
;

Grid loadGrid( constd std::string& filename )

    ...
;

【讨论】:

这并不能解决我的问题。我不想从内存中读取整个 Grid 类,只读取它的几个数据成员。 @Chiel 这并不能直接解决您的问题,因为a)您提供了班级的简化视图(可以,在这里询问时您应该做什么),b)这个答案提供解释为什么你的设计是错误的,以及处理这种情况的正确方法是什么。使解决方案正常工作是您的工作:) @Chiel 然后不要阅读整个网格类。关键是要分离职责。 但是你怎么想象它呢? loadGrid 返回一个 Grid 对象,该对象正在填充已从磁盘读取的所有数据,我没有调用 Grid 网格,而是调用 Grid grid = loadGrid("banana")? @Chiel 完全正确。你已经搞定了【参考方案2】:

解决设置具有复杂行为的 const 成员的一种方法是使用函数初始化它们。在您的情况下,如果我理解正确,这些成员是使用一个函数调用初始化的,因此最好该函数只返回成员的值,以便您可以设置 const 成员。 应该是这样的:

class Grid

  public:
    Grid() : data( readFromInputFile() )   
  private:
    struct Data
    int i; int j; int k;
    ;
    const Data data;
;

这个简单的替代方案应该可以解决您的问题。唯一需要改变的是访问数据的方式,data.i 而不是 i。一旦数据被初始化(readFromInputFile() 也返回一个数据),它就不能被改变。

如果您需要 readFromInputFile() 不是成员或静态成员函数,则将 Data 的定义移到类之外或将其公开。

【讨论】:

一种变体是让Data 实际上是Grid 的基类;那么你可以在引用时使用i而不是data.i @MattMcNabb A private base 是的,但是只有在该基础在其他地方重用时才需要这样做,否则语法成本非常便宜,没有必要这样做。 但这使得与班级一起工作变得不那么愉快了。该类包含大量操作函数,循环遍历 i、j 和 k,并从数组值 [i + aj + bk] 中读取,这变得非常不可读。 如果readFromInputFileGrid 的非静态成员函数,则在实际构造对象之前调用所述成员。 (甚至还没有输入构造函数体,更不用说完成了)。我当然可以看到 static 或非成员直接工作,该函数与类友好以访问私有类型。 是的,这基本上是基于问题的第一个版本的黑客攻击。现在已经澄清了,如果可以分别初始化 i、j 和 k,则经过验证的答案要好得多。仅当无法单独初始化数据并且您无法更改架构时才使用此 hack。否则,仅围绕不可变数据重新组织事物会更好。

以上是关于C++类中数据成员初始化的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 在派生类中静态初始化基类受保护的成员变量

在 C++ 类中使用复杂函数初始化 const 成员

1.类中数据成员的声明与初始化总结

C++特殊成员

C++静态成员变量及其初始化

C++中类的静态成员初始化