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

C++ 函数/方法如何在内部返回对对象的引用,c++,pointers,object,reference,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;

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

#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;
}
#包括
#包括
IPair类{
公众:
IPair(常量字符*s):s(s){
缓冲区=malloc(1024);
};
虚拟~IPair(){
自由(缓冲);
}
虚空打印()常量=0;
常量字符*s;
空*缓冲区;
};
类对:虚拟公共IPair{
公众:
Pair(const char*s):IPair(s){};
虚空打印()常量覆盖{
printf(“你好%s\n”,s);
}
};
对createPair(常量字符*s){
返回对;
}
IPair和usePair(IPair和pair){
pair.print();
返回对;
}
int main(int argc,字符**argv)
{
对a=创建对(“AAA”);
对b=创建对(“BBB”);
使用配对(a);
IPair&x=usePair(b);
使用对(x);
返回0;
}
如果使用valgrind进行检查,则没有内存泄漏-例如,在正确的“位置”调用析构函数

这提出了以下问题:

  • createPair()中到底发生了什么?看起来对象内存被复制了。它是memcpy()-类似于复制构造函数还是与复制构造函数有关
    
  • usePair()获取引用,然后返回相同的引用。由于引用的对象仍在main()范围内,因此这应该是安全的操作-此假设正确吗
  • 在创建对中,构造一个对象,然后返回。这涉及到一个复制构造函数(如果Pair实现了移动构造函数,则可以避免)。此外,RVO(返回值优化)可能有助于避免不必要的复制)
  • usePair处理引用,此处不进行复制。很好
  • 附加声明IPair虚拟的析构函数

  • 在创建对中,构造一个对象,然后返回。这涉及到一个复制构造函数(如果Pair实现了移动构造函数,则可以避免)。此外,RVO(返回值优化)可能有助于避免不必要的复制)
  • usePair处理引用,此处不进行复制。很好
  • 附加声明IPair虚拟的析构函数

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

  • 引用与C++中的指针几乎相同,因此当返回引用时,返回对象的地址。不同之处在于,引用不需要解引用运算符,只能指定一次

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

  • 引用与C++中的指针几乎相同,因此当返回引用时,返回对象的地址。不同之处在于,引用不需要解引用运算符,只能指定一次


    有什么理由使用malloc而不是新的或智能指针吗?这是内存泄漏模拟。没有特别的理由使用malloc而不是新的或智能指针?这是内存泄漏模拟。没有特别的原因实际上,编译器生成的复制构造函数按值复制成员-包括调用拥有它们的成员的复制构造函数。此外,实现RVO和/或将“按值结构”转换为“按引用结构”依赖于编译器—并非所有编译器都会这样做。实际上,编译器生成的复制构造函数会按值复制成员—包括调用拥有这些成员的成员的复制构造函数。此外,实现RVO和/或将按值结构转换为按引用结构依赖于编译器-并非所有编译器都这样做。