Code前端首页关于Code前端联系我们

理解C++结构函数,提升代码可读性和可靠性

terry 2年前 (2023-10-01) 阅读数 153 #c++
文章标签 winxpphpmysql

一、结构函数简介

结构函数(构造函数)是一个特殊的成员函数,主要作用是在创建对象时对其进行初始化操作。在C++中,每个类可以拥有一个或多个结构函数,且结构函数名称与类名称相同,没有返回值类型,可以有参数或不带参数。当对象被创建时,结构函数会自动调用,完成对象的初始化工作。
class Person {
public:
    Person() {
        name = "Unknown";
        age = 0;
    }
    Person(string n, int a) {
        name = n;
        age = a;
    }
private:
    string name;
    int age;
};
上述代码定义了一个Person类,并定义了两个结构函数。第一个结构函数不带参数,用于默认初始化name为“Unknown”、age为0;第二个结构函数带有两个参数,用于指定类成员的值。在创建Person对象时,就会自动调用结构函数进行初始化。

二、结构函数分类

C++结构函数可分为默认结构函数、拷贝结构函数、移动结构函数和转换结构函数等几种类型。 1. 默认结构函数 在类中没有定义结构函数时,编译器会自动生成一个默认结构函数。如果不需要自定义结构函数,可以直接使用默认结构函数。
class Person {
public:
    string name;
    int age;
};
Person p; // 调用默认结构函数初始化
2. 拷贝结构函数 拷贝结构函数用于在对象之间进行赋值或参数传递时调用。拷贝结构函数有两种形式: a) 浅拷贝结构函数:成员变量逐一进行复制,指针成员变量仍指向同一内存地址。
class Person {
public:
    Person(int a, char* n) {
        age = a;
        name = new char[strlen(n)+1];
        strcpy(name, n);
    }
    Person(const Person &p) { // 拷贝结构函数
        age = p.age;
        name = p.name; // 浅拷贝,指针成员变量仍指向同一地址
    }
    ~Person() {
        delete[] name; // delete释放new申请的内存
    }
private:
    char* name;
    int age;
};
Person p1(18, "Tom");
Person p2 = p1; // 调用拷贝结构函数
在上述代码中,用new动态申请了一段内存来存储类成员name的值。在拷贝结构函数中,进行了浅拷贝,即将指针成员变量直接复制,不重新分配内存。这样会导致p1和p2的name指针变量都指向同一块内存地址,造成内存重复释放问题。 b) 深拷贝结构函数:对指针成员变量进行新的内存分配,复制值到新的内存空间中。
class Person {
public:
    Person(int a, char* n) {
        age = a;
        name = new char[strlen(n)+1];
        strcpy(name, n);
    }
    Person(const Person &p) { // 拷贝结构函数
        age = p.age;
        name = new char[strlen(p.name)+1]; // 深拷贝,重新分配内存
        strcpy(name, p.name);
    }
    ~Person() {
        delete[] name; // delete释放new申请的内存
    }
private:
    char* name;
    int age;
};
Person p1(18, "Tom");
Person p2 = p1; // 调用拷贝结构函数
在上述代码中,在拷贝结构函数中重新分配了一段新的内存空间,将原指针成员变量的值复制到新的空间中,避免了内存重复释放问题。 3. 移动结构函数 移动结构函数用于在对象之间进行赋值操作时调用,且源对象的资源不需要保留。在移动结构函数中,首先进行资源的交换,然后将源对象的资源清空。
class Person {
public:
    Person(int a, string n) {
        age = a;
        name = n;
    }
    Person(Person &&p) { // 移动结构函数
        age = p.age;
        name = p.name;
        p.name = ""; // 清空源对象的资源
    }
private:
    string name;
    int age;
};
Person p1(18, "Tom");
Person p2 = move(p1); // 调用移动结构函数
在上述代码中,使用move()函数调用了移动结构函数,进行资源的移动和清空。 4. 转换结构函数 转换函数(类型转换函数)用于将一个类类型对象转换为另一个类型的对象,可以使用显示或隐式类型转换。转换结构函数没有返回值类型,名称和类名称相同,可以有或没有参数。

三、结构函数的特殊条件

1. 虚拟结构函数 虚拟结构函数(虚构造函数)是一个声明为虚拟的结构函数。在一个继承关系的类中,当通过指针或引用调用一个虚拟结构函数时,会自动调用最适当的版本,即最终派生类实现的版本。使用虚拟结构函数的主要目的是实现运行时多态。
class Person {
public:
    virtual ~Person() {} // 定义虚拟结构函数
};
class Student : public Person {
public:
    ~Student() {}
};
Person* p = new Student(); // 使用指针调用虚拟结构函数
delete p; // 调用最终派生类的析构函数
在上述代码中,定义了一个虚拟结构函数,在派生类中重新定义了析构函数。在创建Student对象时,使用指针访问虚拟结构函数,当释放内存时,自动调用最终派生类Student的析构函数。 2. 纯虚拟结构函数 纯虚拟结构函数(纯虚构造函数)是一个没有实现的虚拟结构函数,其目的是在基类中定义一个接口,强制派生类必须实现该接口。在定义纯虚拟结构函数时,需要在结构函数后面加上“= 0”,表示没有实现该函数。不能直接创建一个纯虚拟结构函数的对象。
class Person {
public:
    virtual void show() = 0;
};
class Student : public Person {
public:
    void show() {
        cout setTime(h, m, s);
    }
private:
    Time* t;
};
class Time {
public:
    Time(int h, int m, int s) {
        hour = h;
        minute = m;
        second = s;
    }
    void setTime(int h, int m, int s) {
        hour = h;
        minute = m;
        second = s;
    }
private:
    int hour;
    int minute;
    int second;
};
在上述代码中,创建了一个Person类和一个Time类,在Person类中创建了一个Time对象的指针t,并在结构函数中对其进行初始化。在Person类中还定义了一个设置时间的函数,通过t指针间接访问Time对象,并设置时间。这样就形成了一个Person对象和一个Time对象之间的依赖关系。 2. 继承的应用 结构函数的重载和继承可用于强制派生类对基类成员进行初始化或重新定义。
class Base {
public:
    Base(int a) {
        num = a;
    }
    virtual void show() {
        cout 

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门