为什么输出与我的期望不同?

Vie*_* Ha 1 c++ c++11

我有一个这样的简单程序:

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()
{
    class B {
    protected:
        int     data = 0;
    public:
        B() { cout << "B() ctor\n";}
        virtual ~B() { cout << "~B()\n"; }
        virtual void method() { cout << "data in B: " << data << "\n"; }
    };

    class A : public B 
    {
        int dataA = 2;
    public:
        A() { cout << "A() ctor\n"; }
        ~A() { cout << "~A()\n"; }
        void method() { cout << "data in A: " << dataA << "\n"; }
    };

    {
        B* fptrList[]{ &B{}, &A{}};
        for (auto& itr : fptrList)
            itr->method();
    }

    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我期望的结果:

B() ctor
B() ctor
A() ctor
data in B: 0
data in A: 2
~A()
~B()
~B()
Run Code Online (Sandbox Code Playgroud)

以下是我运行此程序时的实际结果:

B() ctor
~B()
B() ctor
A() ctor
~A()
~B()
data in B: 0
data in B: 0
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为什么输出与我的期望不同?
  • 在调用~A()和~B()之后如何调用method()?
  • 为什么B类的method()被调用两次?

Sam*_*hik 5

无法解释此程序,因为它表现出未定义的行为.

翻译:它是马车.它正在获取临时对象的地址,然后在临时对象被破坏后尝试取消引用它们.

一个好的C++编译器甚至会告诉你程序坏了,并且拒绝参与这个灾难:

t.C: In function ‘int main()’:
t.C:26:27: error: taking address of temporary [-fpermissive]
         B* fptrList[]{ &B{}, &A{}};
                           ^
t.C:26:33: error: taking address of temporary [-fpermissive]
         B* fptrList[]{ &B{}, &A{}};
                                 ^
Run Code Online (Sandbox Code Playgroud)

这个程序的任何输出都是毫无意义的垃圾.


das*_*ght 5

这是正在发生的事情:

  • 您初始化fptrList为临时变量的地址AB
  • 临时变量在获取地址后立即被销毁,因此您的代码具有未定义的行为.
  • 正在尝试做的事情的正确方法是使用new带有智能指针的运算符,或者在初始化程序之外创建实例.

这是一个可能的解决方案:

{
    B b;
    A a;
    B* fptrList[]{ &b, &a };
    for (auto& itr : fptrList)
        itr->method();
}
Run Code Online (Sandbox Code Playgroud)