C++语法基础--复制控制--复制构造函数 ,赋值操作符 ,析构函数

来源:互联网 发布:英剧推荐知乎 编辑:程序博客网 时间:2024/06/05 09:21
           复制控制(编译器自动实现这些操作)
            *复制构造函数
            *赋值操作符 
            *析构函数    
    




1.复制构造函数
  *当定义一个新对象并用同一个类型的对象对它进行初始化式,将显式使用复制构造函数
  *当将该类型的对象传递给函数或从函数返回该类型的对象是,将隐式使用复制构造函数
  
  C++支持两种初始化式:
  *直接初始化(将初始化式放在圆括号中)
  *复制初始化(使用=符号)
  
 Tips:对于类类型对象
   *直接初始化直接调用与实参匹配的构造函数
   *复制初始化总是调用复制构造函数
   *只有指定单个实参或显式创建一个临时对象用于复制时,才用复制初始化。
   
 重点解析:
     支持初始化的复制形式主要是为了与C的用法兼容,当情况许可时,可以允许编译器跳过复制构造函数直接创建对象,但编译器没有义务这
样做。
     目前,大部分C++编译器都会对返回值进行优化:
     例如:对于下面的main函数中的A  a1=1;本来创建a1时,编译器首先调用接受一个int形参的A构造函数,创建一个临时对象,
     然后,编译器使用A复制构造函数将a1初始化为那个临时对象的副本。但是,这一过程会优化为直接在目标对象上进行构造。
    简单地概括就是:省略了“从构造临时对象-->从临时对象拷贝构造”的过程。
    main函数的其它代码,自行理解。

   




Example:
class A
{
 
public:
    A()
    {
        cout<<"默认构造函数"<<endl;
    }


A(int i)
{
cout<<i<<endl;


}


    A(const  A&)
    {
        cout<<"复制构造函数"<<endl;
        
    }


A& operator=(A &a)
{


 cout<<"复值操作符"<<endl;
 return a;
}


~A()
{


cout<<"析构函数"<<endl;
}


   
};
 
    
A fun()
 {
   A  a;
return a;
 }
 
 
int main()

A a;

cout<<endl;


A  a1=1;


cout<<endl;


A a2=A(2);


cout<<endl;


A a3=A(a);

cout<<endl;


A a4=fun();

cout<<endl;


a4=fun();

    return 0;




运行结果:







2.合成复制构造函数
   *逐个成员初始化,将新对象初始化为原对象的副本
   *如果一个类具有数组成员,则合成复制构造函数将复制数组的每一个元素


  Example:
 class A
{
 
public:
void set()
{
for(int i=0;i<5;i++) 
arr[i]=i;
}


void print()
{
        
       for(int i=0;i<5;i++) 
cout<<arr[i]<<'\t';
}
private:
int arr[5];

};
 
   
int main()

A a;
a.set();
A b=a;
b.print();
//0 1 2 3 4
    return 0;
}








3.禁止复制
  *声明(但不定义)private复制构造函数,可以禁止任何复制类类型对象的尝试
   
  Example:
 class A
{
public:
A(){}
 private:
 A(A &a);
};
 
   
int main()

A a;
//ok
        A b=a;//error

    return 0;
}






4.合成赋值操作符
  *类似于和成复制构造函数,执行逐个成员赋值




5.析构函数
  *撤销类对象是会自动调用析构函数
  *动态分配的对象只有在指向该对象的指针被删除时才撤销
  *当对象的引用或指针超出作用域时,不会运行析构函数
 
 Example:
 class A
{
public:
~A(){cout<<"析构函数"<<endl;}
 
};
 
 
int main()

{
A a;
//对象a超出作用域时,运行析构函数
}

{
A *p=new A();//p指针超出作用域时,不会运行析构函数
}



    return 0;
}


Output:
析构函数







6.合成析构函数
  *合成析构函数按对象创建时的逆序撤销每个非static成员 
  *即使我们编写了自己的析构函数,合成析构函数仍然运行
  *合成析构函数并不删除指针成员所指向的对象
原创粉丝点击