如何在 C++ 中初始化一个 class 对象引用来模拟 NRVO?

how to initialize a class object reference in C++ to simulate NRVO?

我遇到了一个课程编程问题,要求我使用引用传递来初始化 A a(在 func 中初始化 A a)。如何通过 A 的引用调用 A 的构造函数?

#include <iostream>
using namespace std;

class A
{
public:
    int x;
    A()
    {
        cout << "default constructor" << endl;
        x = 1;
    }

    A(int x)
    {   
        cout << "constructor with param = "  << x << endl;
        this->x = x;
    }

    ~A() {
        cout << "destructor" << endl;
    }

    void print() {
        cout << x << endl;
    }
};


void fun(A& a)
{
    a.A::A(10); // error!
    return;
}


int main()
{
    A a; 
    fun(a);
    a.print();
    return EXIT_SUCCESS;
}

这个问题是有背景的。老师要我们复制NRVO(命名为return值优化)结果

#include <iostream>
using namespace std;

class A
{
public:
    int x;
    A()
    {
        cout << "default constructor" << endl;
        x = 1;
    }

    A(int x)
    {   
        cout << "constructor with param = "  << x << endl;
        this->x = x;
    }

    ~A() {
        cout << "destructor" << endl;
    }

    void print() {
        cout << x << endl;
    }
};

A fun() {
    A a = A(10);
    return a;
}


int main()
{
    A a = fun();
    return EXIT_SUCCESS;
}

默认 g++ 编译器:

constructor with param = 10
destructor

如果我们关闭 NRVO: g++ test.cpp -fno-elide-构造函数

constructor with param = 10
destructor
destructor
destructor
destructor

老师要我们通过引用传递来复制NRVO(命名为return值优化)结果。

语法 a.A::A(10); 不正确。

构造函数用于创建class的对象,您不能在已经存在的对象上调用它。即使是构造函数也不能显式调用。它由编译器隐式调用。

来自general-1.sentence-2

Constructors do not have names.

因此,您不能显式调用构造函数。创建 class-type 的对象时,编译器将自动调用构造函数。

不能,不能这样。

引用总是指向已初始化的对象。所以你在调用函数之前就已经失败了。 “return”参数已经初始化。而且你不能再次初始化一个初始化值,这是不合法的。

你可以通过调用

作弊
std::construct_at(&a, 10);

为了真正反映 NRVO,你可以这样:

void fun(A *a)
{
    std::construct_at(a, 10);
}

union UninitializedA {
    std::byte uninitialized[sizeof(A)];
    A a;
};

int main()
{
    UninitializedA u;
    fun(&u.a);
    u.a.print();
    u.a.~A();
    return EXIT_SUCCESS;
}