函数/方法如何返回对象的引用在内部工作

时间:2015-06-25 06:57:31

标签: c++ pointers object reference

这可能是重复的,但假设我们有以下代码

#include <stdio.h>
#include <stdlib.h>

class IPair{
public:
    IPair(const char *s) : s(s){
        buffer = malloc(1024);
    };

    virtual ~IPair(){
        free(buffer);
    }

    virtual void print() const = 0;

    const char *s;
    void *buffer;
};

class Pair : virtual public IPair{
public:
    Pair(const char *s) : IPair(s){};

    virtual void print() const override{
        printf("Hello %s\n", s);
    }
};

Pair createPair(const char *s){
    return Pair(s);
}

IPair & usePair(IPair &pair){
    pair.print();

    return pair;
}

int main(int argc, char** argv)
{
    Pair a = createPair("AAA");
    Pair b = createPair("BBB");

    usePair(a);
    IPair &x = usePair(b);
    usePair(x);

    return 0;
}

如果使用valgrind进行检查,则没有内存泄漏 - 例如析构函数在正确的#34;地点&#34;。

上调用

这提出了以下问题:

  1. createPair()内究竟发生了什么?看起来像对象内存被复制。它是memcpy() - 喜欢还是与复制构造函数有关?
  2. usePair()获取引用,然后返回相同的引用。由于引用的对象仍然在main()范围内,这应该是安全操作 - 这个假设是正确的吗?

2 个答案:

答案 0 :(得分:3)

  1. 在创建对中,构造一个对象然后返回。这涉及一个复制构造函数(如果Pair实现了一个Move构造函数,则可以避免)。另外,RVO(返回值优化)可能有助于避免不必要的复制)
  2. usePair处理引用,此处不进行复制。这完全没问题。
  3. P.S。声明IPair虚拟化的析构函数......

答案 1 :(得分:3)

  1. 与Copy Constructor类似 - 如果没有提供构造函数,编译器将生成一个,基本上是memcpy(*this, rhs, sizeof(*this));。返回值优化,即编译器在目标地址中传递以存储值 - 在大多数情况下,无需复制。 [实际上,所有结构/类返回都将修改调用,以便编译器将要返回的对象作为参考参数传递]

  2. 引用与C ++中的指针几乎相同,因此当您返回引用时,将返回该对象的地址。不同之处在于引用不需要取消引用操作符,并且只能分配一次。