When to call the copy constructor in an object


#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: Prevent the compiler from optimizing and compiling with -fno-elide-constructors
insert image description here

Guess you like

Origin blog.csdn.net/qq_44741914/article/details/130091876