C++面向对象

C++

2. 面向对象

2.1 构造与析构

2.1.1 构造函数

含义:使用一个类的对象时,为其分配完空间后,一般需要对创建的对象的属性进行初始化的操作,这个操作就可以在构造函数中完成。是对象生命周期的起点

函数定义:无返回值,无返回类型,与类名同名,可以有不同的重载。

// 定义
class Person{
public:
    Person(){
        cout << "无参构造" << endl;
    }
    Person(int age){
    cout << "有1参构造" << endl;
    }
    Person(int age, int score){
        cout << "有2参构造" << endl;
    }
};
// 调用
int main(){
    // 创建对象的时候调用构造函数 
    // 1.显式调用
    Person xiaoming1 = Person(); // 无参构造
    Person xiaoming2 = Person(18, 100); // 有2参构造
    Person xiaoming3; //Person xiaoming3()不能加括号,否则会默认在定义函数
    Person xiaoming4(18, 100);
    
    // 2.隐式调用
    Person xiaoming5 = {}; // 无参构造
    Person xiaoming6 = 18; // 有1参构造,如果大括号内只有一个值{18},可以省略大括号
    Person xiaoming7 = {18, 100}; // 有2参构造
    
    // 使用new在堆上创建对象,如果调用无参构造函数,小括号可以省略不写
    // 使用new的方式,在堆上创建对象,这个过程叫实例化
    Person* xiaogming8 = new Person;
    return 0;
    
}

explicit 关键字:修饰构造函数,写在构造函数之前,表示不能通过隐式调用构造函数。

    explict Person(int age){
    cout << "有1参构造" << endl;
    }

注意:

  1. 如果在一个类中没有写任何的构造函数,系统会为其添加一个public权限的无参构造函数,可以让我们创建对象。
  2. 如果我们给一个类写了构造函数,系统不会再为我们提供任何默认的构造函数。

如果我们为一个类写了有参的构造函数,一般会同时写无参的构造函数。

// 构造使用
class Person{
public:
    string name;
    int age;
    string gender;
    int score;
//    Person(){
//        name = "";
//        age = 0;
//        dender = "";
//        score = 0;
//    }
    Person(): name(""), age(0), gender(""), score(0){ } //初始化列表赋值
    
//    Person(string n, int a, string g, int s){ n和name不能相同,a和age不能相同……,同名无法区分
//        name = n;
//        age = a;
//        gender = g;
//        score = s;
//    }
    person(string n = "", int a = 0, string g = "", int s = 0): name(n), age(a), gender(g), score(s){ }
    person(string name, int age, string gender): name(name), age(age), gender(gender){ } //初始化列表赋值则可以同名,会自动区分
};

拷贝构造:根据一个对象,拷贝出另外一个对象,即开辟一块新内存给新对象,将一个对象的属性值拷贝到新对象中。

系统自动提供拷贝函数。
新对象与旧对象的内存地址不同,但是属性值相同。

class Person{
public:
    string name;
    int age;
    Person(){}
    Person(string name, int age) : name(name), age(age) { }
    //自己定义拷贝函数,const常量,Person&p表示引用,引用传递,p是引用,p指向xiaoming,p和xiaoming指向同一个对象
    Person(const Person& p){
    cout << "调用了拷贝函数" << endl;
    name = p.name;
    age = p.age+1;
    }
};
int main(){
    Person xiaoming = Person("xiaoming", 18);
    Person xiaohong = xiaoming;
    cout << "小明的年龄" << xiaoming.age << endl;
    cout << "小红的年龄" << xiaohong.age << endl;
    return 0;
};

2.1.1 析构函数

  1. 析构函数是对象生命周期的终点,在对象空间被销毁之前调用。
  2. 在析构函数中,一般进行资源的释放,堆内存的销毁。
  3. 不能重载,一个类只有一个析构函数。
  4. 使用~开头,不能有参数。
class Person{
    int a;
public:
    Person() : a(0) {}  // 初始化成员变量a为0
    ~Person(){
        cout << "析构函数调用" << endl;
    }
};
int main(){
    Person p;
    return 0;
}

2.2 浅拷贝与深拷贝

  1. 浅拷贝:在拷贝构造函数中,直接完成属性的值拷贝。即拷贝对象和被拷贝对象共享同一个内存空间,修改其中一个对象,另一个对象也会改变。
  2. 深拷贝:在拷贝构造函数中,创建出来新的空间,属性中的指针指向的是新的空间。
class Cat{};
class Person{
public:
    int age;
    Cat* pet;
    Person() {
        age = 0;
        pet = new Cat; //其实存放的是堆内存中Cat的地址
    }
    //拷贝构造函数
    Person(const Person& p){
        //这里默认是浅拷贝
        age = p.age;
        pet = p.pet; //其实传递的是堆内存中Cat的地址,所以拷贝后pet指向的是同一个地址
    }
    ~Person(){
        if (pet != nullptr){
            delete pet;
            pet = nullptr;
        }
    }
};
int main(){
    Person xiaoming;
    Person xiaohong = xiaoming;
    //栈空间里销毁内存是先进后出,所有是先释放xiaohong,再释放xiaoming
    //先释放xiaohong的时候,会调用Cat的析构函数,pet被销毁(即存放Cat的堆内存被销毁)
    //当释放xiaoming的时候,pet已经被销毁(即存放Cat的堆内存已经被销毁),程序就会出现异常
    return 0;
}
//拷贝构造函数
    Person(const Person& p){
        age = p.age;
        //深拷贝
        pet = new Cat; //重新在堆内存中为申请一块空间Cat,将地址赋值给pet
        pet->age = p.pet->age;
        pet->name = p.pet->name;
    }

2.3 this指针

  1. this指针是一个隐含的指针,它指向当前对象的地址。
  2. 当前对象:谁调用这个函数,this就指向谁。
class Person{
public:
    int age;
    int getAge(){
        return this->age; 
        //绝大多数情况下this->age和age是一样的,且this->可以省略
        //但是如果有局部变量与成员变量同名,为避免混淆,this->不可以省略,否则访问的是局部变量
    }
};
int main(){
    Person xiaoming{10};
    Pe
  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值