搜索

首页  >  问答  >  正文

一个关于C++的问题

有以下两段C++代码。第一段为:

#include<iostream>
#include<cstdlib>
using namespace std;

class Pair{ 
public:
    Pair(int a, int b): ma(a), mb(ma+b) {}
    int ma;
    int mb;
};

int main(){
    Pair p(1,2);
    cout << p.ma << " " << p.mb << endl;
    system("pause");
    return 0;
}

运行结果为:
1 3

第二段代码为:

#include<iostream>
#include<cstdlib>
using namespace std;

class Pair{ 
public:
    Pair(int a, int b): ma(a), mb(ma+b) {}
    int mb;
    int ma;
};

int main(){
    Pair p(1,2);
    cout << p.ma << " " << p.mb << endl;
    system("pause");
    return 0;
}

运行结果为:
1 -858993458

两段代码,仅仅是成员变量 ma、mb 的定义顺序不同(第8行、9行不同),为什么运行结果就不一样呢?

百思不得姐!!希望大神指点一二,谢谢。

伊谢尔伦伊谢尔伦2805 天前629

全部回复(4)我来回复

  • 高洛峰

    高洛峰2017-04-17 13:03:01

    请注意使用所谓的初始化器的规则
    它们不是按照初始化器的位置来决定谁先初始化
    而是根据变量谁在前来决定谁先初始化。

    第二段代码由于mb在前,所以mb会被先初始化。
    详细内容应该C++ Primer 5ed上面有的,个人的建议是不要使用互相引用来初始化

    回复
    0
  • 怪我咯

    怪我咯2017-04-17 13:03:01

    这是变量初始化顺序有关,第二段代码中mb在前所以mb先初始化而此时ma还没有初始化是个随机数,所以mb不会是3。在c++类构造函数中的变量初始化顺序只和变量定义的顺序有关,与构造函数中初始化列表的顺序无关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。这点在EffectiveC++中有详细介绍。

    回复
    0
  • 黄舟

    黄舟2017-04-17 13:03:01

    《c++ primer》(中文第 4 版) 说:构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。

    也就是说,你遇到的是一种未定义的行为,这依赖于编译器的具体实现。如果编译器是按照类成员出现的次序进行初始化,那么第一个例子就是正确的,而第二个例子就是错误的(因为 mb 失去了被初始化的机会)。

    回复
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:03:01

    几位大神的回答都很好,无奈只能采纳一个答案,我给第一个先回答的大神吧

    回复
    0
  • 取消回复