标题: 类的构造函数和析构函数
1. 构造函数
概念:构造函数在对象创建时被调用,负责执行必要的初始化操作,包括给私有变量赋值。在C++中,构造函数的名称必须与类的名称相同!!并且没有返回类型。当使用者没有提供构造函数,系统会提供默认构造函数。构造函数在定义对象时会自动调用,不需要手动调用。
MyClass.h
#ifndef _MYCLASS_H
#define _MYCLASS_H
#include <iostream>
using namespace std;
class MyClass
{
private:
int privateVariable;
char *privatedata;
public:
/*构造函数的重载*/
MyClass();// 无参构造函数
MyClass(int a);// 一个参的构造函数
MyClass(int a,const char *b);// 两个参的构造函数
int getPrivateVariable() { // 公有成员函数,用于获取私有变量的值
return privateVariable;
}
};
#endif
MyClass.c
#include "MyClass.h"
MyClass::MyClass() //无参构造函数
{
privateVariable =1;
privatedata= nullptr;
}
MyClass::MyClass(int a) {
privateVariable = a;
privatedata = nullptr; // 初始化为nullptr,可根据实际需要进行更改
}
MyClass::MyClass(int a, const char *b) {
privateVariable = a;
privatedata = new char[strlen(b) + 1]; //分配内存
strcpy(privatedata, b);
}
main.c
#include <iostream>
#include "MyClass.h"
int main(int argc, char const *argv[])
{
//在实例化对象时,自动调用。
MyClass class1; //调用无参构造函数
// MyClass class2(2); //调用一个参数的构造函数
// MyClass class3(3,"佳龙"); //调用两个参数的构造函数
// 访问私有变量
std::cout << class1.getPrivateVariable() << std::endl; // 输出: 1
// std::cout << class2.getPrivateVariable() << std::endl; // 输出: 2
// std::cout << class3.getPrivateVariable() << std::endl; // 输出: 3
// std::cout << class3.privatedata << std::endl; //输出 :佳龙
return 0;
}
(1)初始化参数列表
在C++中,初始化参数列表是在类或结构的构造函数中使用的一种方式,用于在对象创建时初始化成员变量。它位于构造函数的函数体之前,采用 “ :变量名1(变量1的值)”
构造函数的初始化参数列表有助于提高代码的效率和可读性,并可以确保成员变量在进入构造函数体之前被正确初始化。
使用初始化参数列表可以更清晰地显示成员变量的初始化过程,尤其在处理类的成员变量是常量或引用类型时,这是一种必要的做法。
举例:
#include <iostream>
class MyClass
{
private:
int privateMember;
double anotherMember;
public:
// 构造函数的初始化参数列表
MyClass(int value, double another) : privateMember(value), anotherMember(another)
{
// 构造函数的函数体
// 可以在这里进行其他的初始化操作或执行其他逻辑
}
void printMembers() {
std::cout << "privateMember: " << privateMember << ", anotherMember: " << anotherMember << std::endl;
}
};
int main() {
// 在创建对象时,通过构造函数的初始化参数列表进行成员变量的初始化
MyClass myObject(42, 3.14);
// 输出成员变量的值
myObject.printMembers();
return 0;
}
(2)拷贝构造函数
拷贝构造函数是一种特殊的构造函数,用于创建一个对象,其内容是另一个同类型对象的副本。
它通常用于以下情况:
通过值传递参数: 当函数参数为对象时,会调用拷贝构造函数来创建参数的副本。
返回对象: 当函数返回一个对象时,也会调用拷贝构造函数来创建返回值的副本。
特点:
拷贝构造函数的名称与类名相同。
参数是对同类型对象的引用(通常是 const 引用)。
拷贝构造函数负责创建对象的副本。
拷贝构造函数的定义形式如下:
class MyClass {
public:
// 拷贝构造函数
MyClass(const MyClass& other) {
// 实现拷贝逻辑
}
};
实例:
#include <iostream>
class MyClass {
public:
// 构造函数
MyClass(int value) : data(value) {}
// 拷贝构造函数
MyClass(const MyClass& other) : data(other.data) {
std::cout << "Copy constructor called" << std::endl;
}
// 显示数据成员的值
void display() const {
std::cout << "Data: " << data << std::endl;
}
private:
int data;
};
int main() {
MyClass obj1(42); // 调用普通构造函数
MyClass obj2 = obj1; // 调用拷贝构造函数
MyClass obj3(obj1); // 调用拷贝构造函数
obj1.display();
obj2.display();
obj3.display();
return 0;
}
2. 析构函数
概念:析构函数是一种特殊的成员函数,用于在对象生命周期结束时进行资源释放和清理工作。在C++中,一个类只能有一个析构函数,其名称与必须类名相同,且前面加上波浪号 ~。析构函数不能有传入任何参数。如果用户没有定义析构函数,编译器会提供默认的析构函数。构造函数下面的情况下会自动调用,不需要手动调用。
●析构函数在以下情况被自动调用:
Ⅰ.当对象超出作用域时,局部对象的析构函数会被调用。
Ⅱ.在 delete 操作符被用于释放动态分配的对象内存时,析构函数会被调用。
Ⅲ.在对象作为成员被其他对象的析构函数销毁时,析构函数会被调用。
#include <iostream>
class MyClass
{
private:
int *dynamicData;
public:
// 构造函数
MyClass() {
dynamicData = (int *)malloc(sizeof(int));; //使用malloc用来分配“变量”内存
std::cout << "Constructor called" << std::endl;
}
// 析构函数
~MyClass() {
if(dynamicData != NULL)
{
free(dynamicData );//释放“变量”内存
dynamicData = NULL;
}
std::cout << "Destructor called" << std::endl;
}
};
int main() {
// 使用 new 关键字在堆上分配“对象”内存
MyClass *class1 = new MyClass();
// 使用 delete 操作符释放“对象”内存
delete class1;
return 0;
}