对象中拷贝构造函数的调用时机

该代码示例展示了C++中类的构造函数,包括默认构造函数、拷贝构造函数和移动构造函数的实现。同时,文章探讨了赋值运算符重载,包括拷贝赋值和移动赋值的情况,特别是在函数参数传递和返回值时的调用情况。文章强调了防止编译器优化的-fno-elide-constructors选项的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#if 0 
// g++ .\test.cpp -o a.exe -fno-elide-constructors
// 运行.\a.exe
#endif
#include<iostream>
#include<string.h>
class person{
private:
   int age;
   const char* name;
   char gender;
public:
   person();
   person(const char* name,int age,char gender);
   person(const person& p);
   person(person&& p);
   ~person();
   person& operator=(const person& p );
   person& operator=(person&& p );
   void PrintInfo();
};
person::person(){
   std::cout<<"No pragma create"<<std::endl;
}
person::person(const char* name,int age,char gender):name(name),age(age),gender(gender){
   std::cout<<"pragma create"<<std::endl;
   
}
person::person(const person& p){
   this->age = p.age;
   this->gender = p.gender;
   size_t len = strlen(p.name);
   char* temp = new char[len+1];
   strcpy(temp,p.name);
   this->name = temp;
   temp = NULL;
   std::cout<<"copy"<<std::endl;
}
person::person(person&& p){
   this->age=p.age;
   this->gender=p.gender;
   this->name = p.name;
   p.name=NULL;
   std::cout<<"moving"<<std::endl;
}
person::~person(){
      std::cout<<"delete"<<std::endl;
      delete[] name;
}
person& person::operator=(const person& p){
    this->age=p.age;
    this->gender=p.gender;
    size_t len = strlen(p.name);
    char *temp = new char[len+1];
    strcpy(temp,p.name);
    this->name = temp;
    temp=NULL;
    std::cout<<"= operator copy"<<std::endl;
    return *this;
}
person& person::operator=(person&& p){
      this->age=p.age;
      this->gender=p.gender;
      this->name=p.name;
      p.name=NULL;
      std::cout<<"= operator moving"<<std::endl;
      return *this;
}
void person::PrintInfo(){
   std::cout<<"name:"<<this->name<<std::endl;
   std::cout<<"age:"<<this->age<<std::endl;
   std::cout<<"gender:"<<this->gender<<std::endl;
}
void test01(person p){
   // p.PrintInfo();
}
person test02(){
   person p;
   return p;
}
int main(){
   {
      // 拷贝构造函数的调用时机
      // 1.值传递
      { 
         std::cout<<"-------------"<<std::endl;
         person p = {"zpc",25,'M'};
         test01(p);
         std::cout<<std::endl;

      }
      // 2.用一个对象去初始化另外一个对象
      {   
          std::cout<<"-------------"<<std::endl;
          person p = {"zpc",25,'M'};
          person q = p; // person q(p); 
          std::cout<<std::endl;
      }
     
      // 3.局部值变量返回的时候, 这里是值得注意的是的一个地方,如果有移动构造函数的时候是掉用移动构造函数
      {   
          // 这里把移动构造函数注释掉可以看到时moving
          std::cout<<"-------------"<<std::endl;
          person q = test02();
          std::cout<<std::endl;
      }
   }
   {
      // 关于等号赋值运算符(拷贝等号赋值运算符,和移动等号赋值运算符)
      // { 
      //    person p = {"zpc",24,'M'};
      //    person q = p;// 这样实际上是在调用拷贝构造函数,并不是在使用赋值运算符
      // }
      // 1.拷贝等号赋值运算符 因为这边这个是p是一个左值会去调用这个,如果是右值还得看是否有等号移动赋值运算符
      {   
          std::cout<<"------ = copy operator -------"<<std::endl;
          person p = {"zpc",24,'M'};
          person q ;
          q = p; 
          std::cout<<std::endl;
      }
      // 2.移动等号赋值运算符 因为这边这个test02()一个右值还得看是否有等号移动赋值运算符,如果没有还是得调用1
      {    
         std::cout<<"-------- = moving opreator -----"<<std::endl;
         person q ;
         q = test02(); // person p = {"zpc",24,'M'}; q = std::move(p);
         std::cout<<std::endl;
      }
   }

   std::cin.get();
   return 0 ;
}

Note:防止编译器进行优化编译时加上 -fno-elide-constructors
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏牧羊人.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值