当返回类型是一个类时,指向返回值的指针的名称是什么?

时间:2014-02-01 23:42:52

标签: c++ pointers

一个例子:


class A  
{  
    ....  
    A func();  
};  

A A::func()  
{  
...  
return something;  
}  

在汇编级别,编译时,函数A::func实际上有两个参数:第一个是this指针,第二个是临时A的地址对象,由调用者创建以存储返回值。

例如,如果我们编写a.func(),程序将在堆栈中创建一个临时A对象(让我们称之为t),并传递a的地址作为第一个参数,t的地址作为第二个参数,最后调用函数func

以下是我的问题:在A::func的实现中,我们可以获得a的地址 - 它是指针this;但是我们有办法获得t的地址吗?它叫什么名字?

如果我想在返回结果之前做一些内存alloc / free,那么它是有用的。

以下是我想要做的一个例子:

class A
{
    int * data;
    A func();
};

A A::func()
{
    // here "ret_p" is the pointer to the return value (let's pretend that it exists)  
    ret_p->data = new int[some length];  
    ...  
    return * ret_p;  
}

当然,我可以在A::func中创建一个本地对象然后返回它;但是程序将在我的本地对象和调用者创建的临时对象之间进行复制。由于调用者已经创建了一个临时对象,我希望通过直接使用它来节省时间和空间。那可能吗?

嗯,这可能是出于c ++,但我仍然希望......

2 个答案:

答案 0 :(得分:1)

堆栈中没有这样的临时A对象参数(t)。

如果您在里面调用A a1 = a.func();return something;,则会调用copy constructor,相当于此A a1(something);a1something是不同的实例。

如果您在A a1; a1 = a.func();return something;内,则会调用a1 = something; // (operator =)a1something是不同的实例。

如果你在里面拨打A a1 = a.func();return A(p1);,这相当于A a1(p1);,有一个实例a1

如果您直接致电a.func();而未分配内部的var和return something;,则返回时不会发生任何事情。

如果直接调用a.func();而未分配内部的var和return A(p1);,则会构造一个临时对象,然后立即销毁。

如果你在A a1; a1 = a.func();return A(p1);里面,将构造一个临时对象,然后将调用operator = a1 = temp object;,然后销毁临时对象。

供您参考。

毕竟,A a1 = a.func()A a1; a1 = a.func()return something; // a varreturn A(p1); // call constructor会导致不同的行为,我认为您可以正确控制记忆。

答案 1 :(得分:0)

&a提供funccopy elision的一种形式。

无法保证会发生任何事情,并且无法对C ++级别的实施进行访问。

当你说“我想在返回结果之前做一些内存分配/免费”时,我不认为你自己清楚了,你能给出一个具体的例子吗?可能你需要的一切都是通过复制省略,移动运算符和RAII来实现的。


回应你的例子,这是你应该怎么做的。

class A
{
    std :: vector <int> data;
    A func();
};

A A::func()
{
    A ret;
    ret .data .assign (some_length, 123); // or whatever;
    return ret;
}

由于copy elision,可能会自动优化你想要的方式。如果您认为编译器不会删除副本,请添加移动构造函数。

A :: A (A && old)
: data (std :: move (old .data))
{
}

std::vector的移动构造函数将简单地复制指针。如果你想知道 的工作方式,那么这里就是本土的等价物。

class A
{
    int * data;

    // Allocate
    A (size_t size) : data (new int [size]) {}

    // Free, only if we haven't moved.
    ~ A () {if (data) delete [] data;}

    // Move
    A (A && old) : data (old .data) {old .data = nullptr;}

    A (const A &) = delete; // or implement with a new allocation.
}