0
点赞
收藏
分享

微信扫一扫

【C++】构造函数和析构函数

米小格儿 2022-01-23 阅读 48

构造&析构

构造函数 Constructor

也叫构造器,再对象创建的时候自动调用,一般用于完成对象的初始化工作。

struct Person {
int m_age;
Person() {
m_age = 0;
cout << "Person()" << endl;
}
Person(int age) {
m_age = age;
cout << "Person(int age)" << endl;
}
};

特点:

  • 函数名与类同名,无返回值(void都不能写),可以有参数,可以重载,可以有多个构造函数。
  • 一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象

注意:

  • malloc分配的对象不会调用构造函数

    struct Person {
    int m_age;
    Person() {
    cout << "Person()" << endl;
    }
    void run() {
    cout << "run() - " << m_age << endl;
    }
    };
    // 定义在全局区,可以调用构造函数
    Person g_person;
    int main() {
    Person person1;
    // 定义在栈空间,可以调用构造函数
    Person *p = new Person;
    // 定义在堆空间,可以调用构造函数
    delete p;
    Person *p = (Person *) malloc(sizeof(Person));
    p->m_age = 10;
    p->run();
    // 运行结果是:
    // run() - 10
    // 并没有调用构造函数
    free();
    }

    如果要将对象放在堆空间,一定用 new 不要用 malloc

    默认情况下,编译器会为每一个类生成空的无参的构造函数

    修正:在某些特定的情况下,编译器才会为类生成空的无参的构造函数

  • 关于构造函数的调用!

    struct Person { 
    int m_age;
    Person() {
    m_age = 0;
    cout << "Person()" << endl;
    }
    Person(int age) {
    m_age = age;
    cout << "Person(int age)" << endl;
    }
    };
    Person g_person0;
    // Person()
    Person g_person1();
    // 函数声明
    Person g_person2(10);
    // Person(int age)
    int main() {
    Person person0;
    // Person()
    Person person1();
    // 函数声明
    Person person2(20);
    // Person(int age)
    Person *p0 = new Person;
    // Person()
    Person *p1 = new Person();
    // Person()
    Person *p2 = new Person(30);
    // Person(int age)
    getchar();
    return 0;
    }

    表面上来看一共调用了9次对象,其中3次是传入参数的,输出应该有6个Person(),3个Person(int age)

    但实际上只有4个Person(),3个Person(int age)

    因为 Person g_person1()Person person1()函数声明,并非调用构造函数!!!

  • 成员变量的初始化

    // 全局区:成员变量初始化为0
    Person g_person;
    int main() {
    // 栈空间:没有初始化成员变量
    // Person person; 直接写会报错
    // 堆空间:没有初始化成员变量,输出 -842150451
    Person *p0 = new Person;
    // 堆空间:成员变量初始化为0
    Person *p1 = new Person();
    }

    但如果在类里加一个空的构造函数

    struct Person {  
    int m_age;
    Person() {
    }
    };
    // 全局区:成员变量初始化为0
    Person g_person;
    int main() {
    // 栈空间:没有初始化成员变量
    // Person person; 直接写会报错
    // 堆空间:没有初始化成员变量,输出 -842150451
    Person *p0 = new Person;
    // 堆空间:不再会自动初始化成员变量,输出 -842150451
    Person *p1 = new Person();
    }
    • 结论:如果自定义了构造函数,除了全局区,其他内存空间的成员变量默认都不会初始化,需要开发人员手动初始化

析构函数 Destructor

在对象销毁的时候自动调用,一般用于完成对象的清理工作,避免内存泄漏(该释放的内存没有得到释放)。

struct Person {  
int m_age;
// 新的Person对象诞生的象征
Person() {
cout << "Person::Person()" << endl;
}
// 一个Person对象销毁的象征
~Person() {
cout << "~Person()" << endl;
}
};
void test() {
Person person;
}
int main() {
cout << "1" << endl;
test();
cout << "2" << endl;
getchar();
return 0;
}
// 输出
// 1
// Person::Person()
// ~Person()
// 2
  • 特点

    函数名以~开头,与类同名,无返回值,无参,不可以重载,有且只有一个析构函数。

  • 注意

    • 通过 malloc 分配的对象 free 的时候不会调用析构函数。

    • class 中构造函数、析构函数要声明为 public 才能被外界正常使用。

    • 对象内部申请的堆空间,由对象内部回收

      struct Car {   
      int m_price;
      Car() {
      cout << "Car::Car()" << endl;
      }
      ~Car() {
      cout << "~Car()" << endl;
      }
      };
      struct Person {
      int m_age;
      Car *m_car;
      Person() {
      m_age = 0;
      m_car = new Car();
      cout << "Person::Person()" << endl;
      }
      ~Person() {
      delete m_car;
      // 需要再将m_car在堆空间的内存手动释放
      cout << "~Person()" << endl;
      }
      };
      int main() {
      {
      Person person;
      }
      getchar();
      return 0;
      }

在这里插入图片描述

如果不在person的析构函数中加`delete m_car;`的话

Person会析构,car不会析构。需要在main函数手动释放,封装性不强。

- 都在栈空间

```C++
struct Car {
int m_price;
};
struct Person {
int m_age;
Car *m_car;
};
Person p;
```

在这里插入图片描述

  • 都在堆空间

    在这里插入图片描述

    struct Car {  
    int m_price;
    };
    struct Person {
    int m_age;
    Car *m_car;
    };
    Person *p = new Person();

    在这里插入图片描述

    struct Car { 
    int m_price;
    };
    struct Person {
    int m_age;
    Car *m_car;
    Person() {
    m_car = new Car();
    }
    ~Person() {
    delete m_car;
    }
    };
    Person *p = new Person();

举报

相关推荐

0 条评论