如何在C+&#x2B中初始化类对象引用模拟nrvo?

发布于 2025-01-28 14:58:11 字数 1692 浏览 3 评论 0原文

我遇到了一个课程编程问题,该问题要求我使用通过参考的传递(在func中初始化a a初始化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(命名返回值优化)结果。

#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-constructors

constructor with param = 10
destructor
destructor
destructor
destructor

老师希望我们通过参考通过传递来复制NRVO(命名返回值优化)结果。

I meet a course programming problem, which asks me to initialize the A a using passing by reference (initialize the A a in the func). How can I call A's constructor by A's reference?

#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;
}

There is a background of this problem. The teacher want us to replicate the NRVO(named return value optimization) result.

#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;
}

default g++ compiler:

constructor with param = 10
destructor

if we close the NRVO:
g++ test.cpp -fno-elide-constructors

constructor with param = 10
destructor
destructor
destructor
destructor

The teacher want us to replicate the NRVO(named return value optimization) result by passing by reference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不必你懂 2025-02-04 14:58:11

语法aa :: A(10);是不正确的。

构造函数用于创建类的对象,您无法在已经存在的对象上调用它。即使是构造函数也无法明确调用。它是由编译器暗中调用的。

来自 eneral-1.Sentence-2

构造函数没有名称。

因此,您无法明确调用构造函数。当创建该类类型的对象时,编译器将自动调用构造函数。

The syntax a.A::A(10); is incorrect.

Constructor is used to create an object of a class, you cannot call it on an already existing object. Even a constructor cannot be explicitly called. It is implicitly called by the compiler.

From general-1.sentence-2:

Constructors do not have names.

Thus, you cannot call a constructor explicitly. The compiler will automatically call the constructor when an object of that class-type is created.

你好,陌生人 2025-02-04 14:58:11

你不能,不能这样。

引用总是指向初始化对象。因此,在调用该函数之前,您已经失败了。 “返回”参数已经初始化。而且您不能再次初始化初始化值,而不是合法的。

您可以通过呼吁

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;
}

You can not, not like this.

A reference always points to an initialized object. So you already failed before you called the function. The "return" argument is already initialized. And you can't initialized an initialized value again, not legally.

You can cheat by calling

std::construct_at(&a, 10);

For it to really reflect NRVO you could have something like this:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文