C++中拷贝构造函数的调用与C++返回值优化

来源:互联网 发布:eve mac 国服 编辑:程序博客网 时间:2024/05/26 08:43

C++中的拷贝构造函数

class Dog{private:    std::string name;    int id;public:    int *buf;    Dog(){        std::cout<<"default constructor invoked"<<std::endl;    }    Dog(const Dog &dog){//这个就是Dog类的拷贝构造函数        std::cout<<"copy constructor invoked"<<std::endl;        this->name = dog.name;        this->id = dog.id;        this->buf = (int *)malloc(10*sizeof(int));        memcpy((void *)(this->buf), (void *)dog.buf, 10);    }    void applyForBuf(){        buf = (int *)malloc(10 * sizeof(int));        std::cout<<"address of buf is"<<buf<<std::endl;    }};

如下代码所示,在main函数中调用fuck(Dog)方法的时候,会进行Dog对象的复制,在fuck(Dog) 的函数栈中,会建立一个Dog对象的拷贝。如果Dog类没有提供拷贝构造函数,编译器会提供一个默认的拷贝构造函数,即浅拷贝

void fuck(Dog dog){    std::cout<<"address of buf is"<<dog.buf<<std::endl;}int main(int argc, char *argv[]){    Dog d;    std::cout<<"address of new buf is"<<d.buf<<std::endl;    fuck(d);    return 0;}

浅拷贝会将指定对象的成员变量复制到目标对象,对象当中的指针成员变量也是。这会造成一个问题,如果浅拷贝完成后释放指定对象的指针成员变量指向的堆内存区域,目标对象对此并不知情,如果它对这块内存进行操作,就会引发异常。
与浅拷贝对应的是深拷贝,除了将指定对象的成员变量复制到目标对象,同时为目标对象的指针变量分配内存,并进行复制。当执行上述代码时,由于指定了拷贝构造函数,所以在执行fuck(d)方法的同时也为fuck(d)栈区域中的dog.buf分配了一段新内存。可以看到两个对象的buf指针变量指向不同的内存地址。

default constructor invoked
address of new buf is0x4018ef
copy constructor invoked
address of buf is0x397ac8

另外一种拷贝构造函数的调用时机是当声明一个类的对象并赋值时,如下所示

int main(int argc, char *argv[]){    Dog d;    Dog e = d;//注意,此时调用的是拷贝构造函数,深拷贝    Dog f;    f = d;//赋值操作,浅拷贝,除非在Dog类中重载“=”操作符    return 0;}

C++的返回值优化

原创粉丝点击