C++拷贝构造函数

拷贝构造函数调用的时机是当以拷贝的方式初始化对象时会调用拷贝构造函数,这里需要注意两个关键点,分别是以拷贝的方式和初始化对象;

在定义的同时进行复制叫做初始化,定义完成以后再赋值(不管定义的时候有没有赋值)就叫做赋值。初始化只能由一次,赋值可以由很多次;

//普通构造函数
Student::Student(string name , int age )
{
    m_name = name;
    m_age = age;
}
//拷贝构造函数
Student::Student(const Student &Stu)
{
    this->m_name = Stu.m_name;
    this->m_age = Stu.m_age;
    cout << "Copy constructor was called." << endl;
}
// 重载 = 运算符
Student& Student:: operator=(const Student &Stu)
{
    this->m_name = Stu.m_name;
    this->m_age = Stu.m_age;
    cout << "operator=() was called." << endl;
    return *this;
}

int main()
{
    Student stu1("Xiao Ming", 18);  // 调用普通构造函数
    Student stu2("Xiao Wang", 18);  // 调用普通构造函数
    Student stu3 = stu1;  // 调用拷贝构造函数
    stu3 = stu2;  //调用operator=()
    Student stu4(stu1);   // 调用拷贝构造函数
    Student stu5; // 调用普通构造函数
    stu5 = stu2;  //调用operator=()
    return 0;
}

以拷贝的方式来初始化对象的几种情况:

将其它对象作为实参

Student stu1("Xiao Ming", 18);  // 普通初始化
Student stu4(stu1);   // 以拷贝的方式进行初始化
/* 即使我们不在类中显示定义拷贝构造函数,这种初始化方式也是有效的,编译器会生成默认的拷贝构造函数 */

在创建对象的同时赋值

Student stu1("Xiao Ming", 18);  // 普通初始化
Student stu3 = stu1;  // 以拷贝的方式进行初始化
/* 这是最常见的一种以拷贝的方式初始化对象的情况 */

函数的形参为类类型

如果函数的形参为类类型(对象),那么调用函数时要将另外一个对象作为实参传递进来赋值给形参,这也是以拷贝的方式初始化形参对象,如下所示。

void func(Student s){
    //TODO:
}
Student stu1("Xiao Ming", 18);  // 普通初始化
func(stu1);  //以拷贝的方式初始化
 
/* func() 函数有一个 Student 类型的形参 s,将实参 stu 传递给形参 s 就是以拷贝的方式初始化的过程。 */

函数返回值为类类型(与编译器有关不绝对)

      当函数的返回值为类类型时,return 语句会返回一个对象,不过为了防止局部对象被销毁,也为了防止通过返回值修改原来的局部对象,编译器并不会直接返回这个对象,而是根据这个对象先创建出一个临时对象(匿名对象),再将这个临时对象返回。而创建临时对象的过程,就是以拷贝的方式进行的,会调用拷贝构造函数,如下所示

Student func(){
   Student stu1("Xiao Ming", 18);  // 普通初始化
    return stu1;
}
Student stu = func();

C++运算符重载

运算符重载的基本格式

operator重载的运算符(参数表)
   {
   ……
   }

 operator是关键字,它与重载的运算符一起构成函数名。

运算符重载的两种方法

类内重载

#include <iostream>
using namespace std;

class Point{
public:
    Point(){};
    Point (int x, int y): x(x),y(y) {};
    Point operator+(const Point &b){ //类内重载,运算符重载函数作为类的成员函数
        Point ret;
        ret.x = this->x + b.x;
        ret.y = this->y + b.y;
        return ret;
    }
    int x,y;
};

int main() {
    Point a(2,4),b(5,3);
    Point c = a + b;      //这里c++编译器会,自动去找 + 运算符的重载函数
	cout<< "x :" << c.x << endl;
    cout<<"y :" << c.y << endl;
}

类外重载(用友元函数的方法实现)

#include <iostream>
using namespace std;

class Point{
public:
    Point(){};
    Point (int x, int y): x(x),y(y) {};
    friend Point operator+(const Point &, const Point &);   //声明类的友元函数
    int x,y;
};

Point operator+(const Point &a,const Point &b){//类外重载,运算符重载函数作为类的友元函数
    Point ret;
    ret.x = a.x + b.x;
    ret.y = a.y + b.y;
    return ret;
}

int main() {
     Point a(2,4),b(5,3);
    Point c = a + b;
	cout<< "x :" << c.x << endl;
    cout<<"y :" << c.y << endl;
}