成员初始值设定项列表中临时的构造和销毁顺序

问题描述 投票:0回答:1

考虑下面的代码,

C
的MIL内的临时对象什么时候会被销毁?当词法上包含临时创建的完整表达式完成时,临时对象将被破坏。然而,MIL 是一个表达式吗?如果是这样,这种情况下的完整表达式是什么?

#include <iostream>
class A {
    public:
    A() {
        std::cout << "Default Constructor of A\n";
    }
    ~A() {
        std::cout << "Destructor of A\n";
    }
};
class B {
    public:
    B() {
        std::cout << "Default Constructor of B\n";
    }
    ~B() {
        std::cout << "Destructor of B\n";
    }
};
class C {
    A a;
    B b;
    public:
    C() : a(A()), b(B()) {
    }
};
int main() {
    C c;
}

使用

-std=c++17
编译的 Apple Clang 的输出显示

Default Constructor of A
Default Constructor of B
Destructor of B
Destructor of A

但是我想问以下是否也可以:

Default Constructor of A
Destructor of A
Default Constructor of B
Destructor of B
c++ language-lawyer
1个回答
0
投票

不,底部的东西是不可能的。等效代码是

class C {
    A a;
    B b;
    public:
    C() {
    }
};
首先构造

a
,其次构造
b

您可能想询问这样的代码

#include <iostream>

class A {
 public:
  A() { std::cout << "Default Constructor of A\n"; }
  ~A() { std::cout << "Destructor of A\n"; }
};

class B {
 public:
  B() { std::cout << "Default Constructor of B\n"; }
  ~B() { std::cout << "Destructor of B\n"; }
};

A GetA() {
  std::cout << "GetA\n";
  return A{};
}

B GetB() {
  std::cout << "GetB\n";
  return B{};
}

class C {
  A a;
  B b;

 public:
  C() : a(GetA()), b(GetB()) {}
};

int main() { C c; }

然后指定“GetA”和“GetB”的顺序可能就是你想要的。

GetA
Default Constructor of A
GetB
Default Constructor of B
Destructor of B
Destructor of A

即使您像下面这样调用,初始化顺序也是由声明的顺序指定的。

C() : b(GetB()), a(GetA()) {}
© www.soinside.com 2019 - 2024. All rights reserved.