C ++调用方法尚未构造的对象

时间:2016-01-14 23:16:01

标签: c++

我最后一次被投票,所以我试图让我的问题更清楚。 这是代码:

my_header.h

<script>
        var Notification = window.Notification || window.mozNotification || window.webkitNotification;

        Notification.requestPermission(function (permission) {
            // console.log(permission);
        });

        function show() {
            var instance = new Notification(
                "Hey", {
                    body: "this is a message"
                }
            );

            instance.onclick = function () {
                // Something to do
            };
            instance.onerror = function () {
                // Something to do
            };
            instance.onshow = function () {
                // Something to do
            };
            instance.onclose = function () {
                // Something to do
            };

            return false;
        }
    </script>

和main.cc

class A;

class B {
public:
  B(A* a);

  int GetValue() { return value_; }

private:
  int value_;
};

class A {
public:
  A() {
   b = new B(this);
  }

  void PrintValue() {
    std::cout <<  "GetValue() called from A::PrintValue() = " << b->GetValue() << "\n";
  }

private:
  B* b;
};

B::B(A* a) : value_(100) {
  std::cout << "GetValue() called from B::B(A* a) = " << GetValue() << "\n";
  a->PrintValue();
}

输出结果为:

    #include "my_header.h"

    int main() {
      A a;
      return 0;
    }

我知道调用尚未正确构造的对象方法是一个非常糟糕的主意。但我不明白为什么从GetValue() called from B::B(A* a) = 100 GetValue() called from A::PrintValue() = 1 调用的GetValue()会返回1,即使PrintValue()已经初始化为100,正如我们从上面的字符串中看到的那样。

3 个答案:

答案 0 :(得分:1)

未定义的行为意味着任何事情都可能发生。如你所说,A对象尚未构造,因此使用指向PrintValue对象的指针调用A会产生无意义。不要试图推理它。不要这样做。

答案 1 :(得分:1)

A::b的构造函数完成之后,

B未设置为新B对象的地址。

B的构造函数调用a->PrintValue()时,后者调用b->GetValue()b尚未初始化。因此,您可以通过访问b获得未定义的行为。

答案 2 :(得分:0)

你请求未定义的行为以及编译器给你的东西。 A未完全构建。特别是,b尚未分配,并且未特别初始化为任何内容。你的程序可能会做任何事情。