构造函数

一 构造函数特点

1)自动调用(在创建新对象时,自动调用)
2)构造函数的函数名,和类名相同
3)构造函数没有返回类型
4)可以有多个构造函数(即函数重载形式)

二 构造函数的种类

  • 默认构造函数
  • 自定义的构造函数
  • 拷贝构造函数
  • 赋值构造函数

2.1 默认构造函数

没有参数的构造函数,称为默认构造函数
如果数据成员使用类内初始值,同时又在构造函数中进行了初始化,那么以构造函数中的初始化为准。相当于构造函数中的初始化,会覆盖对应的类内初始值

#include <iostream>
#include <string>
using namespace std;

class Human
{
public:
    Human();
    void description();
private:
    string name;
    int age = 18;  //类内初始值
    int salary;
};

// 默认构造函数
Human::Human()
{
    cout << "调用 Human() " << endl;
    name = "无名";
    age = 20;
    salary = 10000;
}

void Human::description()
{
    cout << "name:" << name << " age:" << age << " salary:" << salary << endl;
}

int main()
{
    Human f1;
    f1.description();
    return 0;
}

image

2.2 自定义构造函数

#include <iostream>
#include <string>
using namespace std;

class Human
{
public:
    Human();
    Human(string name, int age, int salary);
    void description();
private:
    string name;
    int age = 18;  //类内初始值
    int salary;
};

// 默认构造函数
Human::Human()
{
    cout << "调用 Human() " << endl;
    name = "无名";
    age = 20;
    salary = 10000;
}

// 自定义构造函数
Human::Human(string name, int age, int salary)
{
    cout << "调用 Human(string name, int age, int salary) " << endl;
    this->name = name;
    this->age = age;
    this->salary = salary;

}

void Human::description()
{
    cout << "name:" << name << " age:" << age << " salary:" << salary << endl;
}

int main()
{
    Human f1;
    Human f2("小红", 15, 3000);
    f1.description();
    f2.description();
    return 0;
}

image

2.3 拷贝构造函数

#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;

class Human
{
public:
    Human();
    Human(const string name, int age, int salary, const char* addr);
    Human(const Human& man);
    void description();
    void setAddr(const char* addr);
    const char* getAddr();
private:
    string name;
    int age = 18;  //类内初始值
    int salary;
    char* addr;
};

// 默认构造函数
Human::Human()
{
    cout << "调用 Human() " << endl;
    name = "无名";
    age = 20;
    salary = 10000;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, "China");
}

// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
    cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
    this->name = name;
    this->age = age;
    this->salary = salary;
    this->addr = new char[ADDR_LEN];
    strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
    cout << "调用 Human(const Human& man) " << endl;
    name = man.name;
    age = man.age;
    salary = man.salary;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, man.addr);
}

void Human::description()
{
    cout << "name:" << name << " age:" << age 
        << " salary:" << salary << " addr:" << addr << endl;
}

void Human::setAddr(const char* addr)
{
    if (!addr)
    {
        return;
    }
    strcpy_s(this->addr, ADDR_LEN, addr);
}

const char* Human::getAddr()
{
    return addr;
}

int main()
{
    Human f1;
    Human f2("小红", 15, 3000,"广东");
    Human f3(f2);

    f1.description();
    f2.description();
    f3.description();
    f2.setAddr("上海");

    cout << "-----------------------------------" << endl;
    f1.description();
    f2.description();
    f3.description();

    return 0;
}

image

2.4 赋值构造函数

#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;

class Human
{
public:
    Human();
    Human(const string name, int age, int salary, const char* addr);
    Human(const Human& man);
    Human& operator=(const Human&);

    void description();
    void setAddr(const char* addr);
    const char* getAddr();
private:
    string name;
    int age = 18;  //类内初始值
    int salary;
    char* addr;
};

// 默认构造函数
Human::Human()
{
    cout << "调用 Human() " << endl;
    name = "无名";
    age = 20;
    salary = 10000;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, "China");
}

// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
    cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
    this->name = name;
    this->age = age;
    this->salary = salary;
    this->addr = new char[ADDR_LEN];
    strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
    cout << "调用 Human(const Human& man) " << endl;
    name = man.name;
    age = man.age;
    salary = man.salary;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, man.addr);
}

// 赋值构造函数
Human& Human::operator=(const Human& man)
{
    cout << "调用 Human& operator=(const Human& man) " << endl;

    //检测是否是对自己赋值,例如:f1=f1
    if (this == &man)
    {
        return *this;
    }

    name = man.name;
    age = man.age;
    salary = man.salary;

    //如果有必要,需要先释放自己的资源(动态内存)
    //delete[] addr;
    //addr = new char[ADDR_LEN];

    strcpy_s(addr, ADDR_LEN, man.addr);

    //返回对象本身的引用,以便做链式连续处理,例如 f1=f2=f3
    return *this;
}

void Human::description()
{
    cout << "name:" << name << " age:" << age 
        << " salary:" << salary << " addr:" << addr << endl;
}

void Human::setAddr(const char* addr)
{
    if (!addr)
    {
        return;
    }
    strcpy_s(this->addr, ADDR_LEN, addr);
}

const char* Human::getAddr()
{
    return addr;
}

int main()
{
    Human f1;
    Human f2("小红", 15, 3000,"广东");
    Human f3(f2);
    Human f4;

    f4 = f2;
    f1.description();
    f2.description();
    f3.description();
    f4.description();
    f2.setAddr("上海");

    cout << "-----------------------------------" << endl;
    f1.description();
    f2.description();
    f3.description();
    f4.description();

    return 0;
}

image

三 拷贝构造函数调用时机

  • 调用函数时,实参是对象,形参不是引用类型
  • 函数返回值类型是类,而且不是引用类型
  • 对象数组的初始化列表中,使用对象
#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;

class Human
{
public:
    Human();
    Human(const string name, int age, int salary, const char* addr);
    Human(const Human& man);
    Human& operator=(const Human&);

    void description();
    void setAddr(const char* addr);
    const char* getAddr();
private:
    string name;
    int age = 18;  //类内初始值
    int salary;
    char* addr;
};

// 默认构造函数
Human::Human()
{
    cout << "调用 Human() " << endl;
    name = "无名";
    age = 20;
    salary = 10000;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, "China");
}

// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
    cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
    this->name = name;
    this->age = age;
    this->salary = salary;
    this->addr = new char[ADDR_LEN];
    strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
    cout << "调用 Human(const Human& man) " << endl;
    name = man.name;
    age = man.age;
    salary = man.salary;
    addr = new char[ADDR_LEN];
    strcpy_s(addr, ADDR_LEN, man.addr);
}

// 赋值构造函数
Human& Human::operator=(const Human& man)
{
    cout << "调用 Human& operator=(const Human& man) " << endl;

    //检测是否是对自己赋值,例如:f1=f1
    if (this == &man)
    {
        return *this;
    }

    name = man.name;
    age = man.age;
    salary = man.salary;

    //如果有必要,需要先释放自己的资源(动态内存)
    //delete[] addr;
    //addr = new char[ADDR_LEN];

    strcpy_s(addr, ADDR_LEN, man.addr);

    //返回对象本身的引用,以便做链式连续处理,例如 f1=f2=f3
    return *this;
}

void Human::description()
{
    cout << "name:" << name << " age:" << age 
        << " salary:" << salary << " addr:" << addr << endl;
}

void Human::setAddr(const char* addr)
{
    if (!addr)
    {
        return;
    }
    strcpy_s(this->addr, ADDR_LEN, addr);
}

const char* Human::getAddr()
{
    return addr;
}

// 1.调用函数时,实参是对象,形参不是引用类型
void test1(Human man)
{
    man.description();
}

// 2.函数的返回类型是类,而且不是引用类型
Human test2(Human& man)
{
    return man;
}

int main()
{
    Human f1;
    test1(f1);   
    test2(f1);  //会创建一个临时对象,接收test2的返回值

    // 3.对象数组的初始化列表中,使用对象
    Human f2, f3;
    Human man[] = { f1, f2, f3 };

    return 0;
}

image

参考:https://blog.csdn.net/weixin_43831728/article/details/107788822

posted @ 2022-04-28 19:16  荒年、  阅读(283)  评论(0编辑  收藏  举报