C++语言-类中各个重要函数原理

2022-07-29  本文已影响0人  大虾啊啊啊

1、命名空间

引入命名空间,我们就可以使用命名空间里的函数,以及成员

namespace daxiaa {
    char *name;
    int age;

    void show() {
        cout << "name:" << name << " age:" << age << endl;
    }
}

int main() {
    using namespace daxiaa;
    daxiaa::name = "daxiaa";
    daxiaa::age = 100;
    daxiaa::show();
name:daxiaa age:100

2、构造函数

1、先在头文件中声明

    //构造函数
    Student();

    Student(int age);

    Student(int age, char *name);

2、实现文件中实现

/**
 * 无参数构造函数
 */
Student::Student() {
   // cout << "no param construct" << endl;
}
/**
 * 一个参数的构造函数
 * @param age
 */
Student::Student(int age) : Student(age, "daxiaa") {
    //cout << "one param construct age = " << age << endl;
    this->age = age;
}
/**
 * 两个参数构造函数
 * @param age
 * @param name
 */
Student::Student(int age, char *name) {
  // cout << "two param construct age = "  << age << " name = " << name << endl;
  this->age = age;
  this->name = name;

}

3、调用构造函数创建对象

    //调用空参构造函数
    Student stu1;
    stu1.setAge(100);
    stu1.setName("daxiaa");
    cout << "age = " << stu1.getAge() << " name = " << stu1.getName() << endl;
    Student stu2(100);

    Student *stu3 = new Student(100, "daxiaa");
    if (stu3) {
        //手动释放堆空间
        delete stu3;
        stu3 = NULL;
    }

3、析构函数

对象在回收的时候就会首先触发析构函数

Student::~Student() {
    cout << "xi gou function"<< endl;
}

4、对象的拷贝

通过以下方式,我们实现了对象的拷贝,我们可以看到打印结果,对象里的属性结果是一样的。但是对象的内存地址不一样。

    Student student1(100, "xiaoming");
    Student student2 = student1;
    cout << " student1.adress " << &student1 << " student1.name: " << student1.getName()
         << " student1.age: " << student1.getAge() << endl;
    cout << " student2.adress " << &student2 << " student2.name: " << student2.getName()
         << " student2.age: " << student2.getAge() << endl;

 student1.adress 0x70465ff900 student1.name: xiaoming student1.age: 100
 student2.adress 0x70465ff8f0 student2.name: xiaoming student2.age: 100

5、 拷贝构造函数

/**
 * 自定义拷贝构造函数
 * @param student
 */
Student::Student(const Student &student) {
    cout << "kao bei gou zhao hanshu" << endl;
    this->age = student.age + 100;
    this->name = "hello world";
}

    Student student1(100, "xiaoming");
    Student student2 = student1;
    cout << " student1.adress " << &student1 << " student1.name: " << student1.getName()
         << " student1.age: " << student1.getAge() << endl;
    cout << " student2.adress " << &student2 << " student2.name: " << student2.getName()
         << " student2.age: " << student2.getAge() << endl;

 student1.adress 0x2df19ff620 student1.name: xiaoming student1.age: 100
 student2.adress 0x2df19ff610 student2.name: hello world student2.age: 200

可以看到自定义拷贝构造函数之后,两个对象不但地址不一样,成员也被我们修改了。


class Student {
public:
    int age;
    string name;

    Student(int age, string name) {
        this->age = age;
        this->name = name;
    }

    Student(const Student &student) {
        cout << "拷贝构造函数" << endl;
        this->age = student.age;
        this->name = student.name;
    }

    ~Student() {
        cout << "析构函数" << endl;
    }

};


void add(Student student) {
    cout << &student << endl;
}

int main() {
    Student student(18, "小红");
    add(student);
    cout<<&student<<endl;
}
拷贝构造函数
0xadcc9ffb10
析构函数
0xadcc9ffab0
析构函数

这种方式传递对象参数,会调用拷贝构造函数,main函数和add函数中的student为两个对象

void add(Student & student) {
    cout << &student << endl;
}

int main() {
    Student student(18, "小红");
    add(student);
    cout<<&student<<endl;

}
0x488a7ffba0
0x488a7ffba0
析构函数

main函数和add函数的student的地址一样,并且没有调用拷贝构造函数。

6、常量指针、指针常量、 常量指针常量

    int number = 9;
    int number2 = 8;

    // 大道至简 一分钟搞定

    // 常量指针
    const int * numberP1 = &number;
    // *numberP1 = 100; // 报错,不允许去修改【常量指针】存放地址所对应的值
    // numberP1 = &number2; // OK,允许重新指向【常量指针】存放的地址

    //  指针常量
    int* const numberP2 = &number;
    *numberP2 = 100; // OK,允许去修改【指针常量】存放地址所对应的值
    // numberP2 = &number2; // 报错,不允许重新指向【指针常量】存放的地址

    // 常量指针常量
    const int * const numberP3 = &number;
    // *numberP3 = 100; // 报错,不允许去修改【常量指针常量】存放地址所对应的值
    // numberP3 = &number2; // 报错,不允许重新指向【常量指针常量】存放的地址

7、深拷贝和浅拷贝

/**
 * 自定义拷贝构造函数 - 浅拷贝
 * @param student 常量引用
 */
Student::Student(const Student &student) {
    cout << "qian kao bei gou zhao hanshu" << endl;
    this->age = student.age + 100;
    this->name = "hello world";
    // 浅拷贝
    this->sex = student.sex;
}
/**
 * 自定义拷贝构造函数 -深拷贝
 * @param student 常量引用
 */
Student::Student(const Student &student) {
    cout << "shen kao bei gou zhao hanshu" << endl;
    this->age = student.age + 100;
    this->name = "hello world";
    //深拷贝
    this->sex = (char *) malloc(sizeof(char *) * 10);
    strcpy(this->sex, student.sex);
}

所谓的浅拷贝和深拷贝,就是在定义拷贝函数中,拷贝过来的属性是直接通过 = 号赋值的方式,还是另外在堆空间开辟内存,通过拷贝的方式。前者就是浅拷贝,后者则为深拷贝。
主要用途:
当我们的类中的成员属性是通过malloc在堆空间开辟过来的,如果我们使用浅拷贝,这样两个对象中的这个成员都指向同一块堆空间,这样一来在析构函数中手动释放对象中的成员的时候就会造成重复释放两次同一块堆空间,在一般平台下都会报错,因此这个时候我们就需要使用到深拷贝。使得拷贝之后两个对象的同一个成员,都指向不同的堆空间。

上一篇 下一篇

猜你喜欢

热点阅读