美文网首页
C++语言-类中各个重要函数原理

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

作者: 大虾啊啊啊 | 来源:发表于2022-07-29 00:27 被阅读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为两个对象

  • 解决对象传递拷贝对象问题
    使用引用的方式,类似Java的对象参数传递一样
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在堆空间开辟过来的,如果我们使用浅拷贝,这样两个对象中的这个成员都指向同一块堆空间,这样一来在析构函数中手动释放对象中的成员的时候就会造成重复释放两次同一块堆空间,在一般平台下都会报错,因此这个时候我们就需要使用到深拷贝。使得拷贝之后两个对象的同一个成员,都指向不同的堆空间。

相关文章

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

    1.命名空间的自定义及使用 全局使用及局部使用。 命名空间变量及函数重复的使用方式 命名空间嵌套 2.构造函数详解...

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

    1、命名空间 引入命名空间,我们就可以使用命名空间里的函数,以及成员 自定义命名空间 2、构造函数 1、先在头文件...

  • C++如何实现一个接口类

    原理 C++中,通过类实现面向对象的编程,而在基类中只给出纯虚函数的声明,然后在派生类中实现纯虚函数的具体定义的方...

  • C++多态——虚函数表vtable

    纯Swift类的函数调用原理,类似于C++的虚函数表 纯Swift类的函数调用,类似于C++的虚函数表,是编译时决...

  • C/C++ 函数地址

    C 函数 C 语言中没有类的概念,只有普通的函数。 控制台输出: C++ 函数 C++ 函数有如下几种: 1)普通...

  • C++的this和Objective-C的self

    C++中定义类的实例方法如下: C++编译器将该方法作为C语言函数来处理 MyClass::method方法的实质...

  • C/C++编程笔记:C语言和C++语言的 struct 对比!区

    1. C++语言将struct当成类来处理的,所以C++的struct可以包含C++类的所有东西,例如构造函数,析...

  • pybind11—类(继承,重载,枚举)

    前言 在C++类中, 继承, 函数重载是重要的特征。 继承 重载 overloadpy::overload_cas...

  • [初学C++]构造和析构函数

    什么是构造函数定义C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数.C++对类提...

  • 深刻剖析之c++博客文章

    三大特性 封装、继承、多态 多态 C++ 虚函数表解析C++多态的实现原理 介绍了类的多态(虚函数和动态/迟绑定)...

网友评论

      本文标题:C++语言-类中各个重要函数原理

      本文链接:https://www.haomeiwen.com/subject/pvkxwrtx.html