c++类和对象中
重点是构造,析构,拷贝构造和赋值重载这四个函数。构造函数是特殊的成员函数,名字虽然叫做构造,但他不是用来开空间的,而是来完成初始化工作的。当实例化对象完成后,就会调用构造函数来对成员变量进行初始化。构造函数的特点:(1)函数名与类名相同。(2)无返回值(返回值什么都不写,void也不写)(3)对象实例化时系统会自动调用构造函数(4)构造函数可以重载代码语言:javascriptAI代码解释(5)如
重点是构造,析构,拷贝构造和赋值重载这四个函数。
2,构造函数
构造函数是特殊的成员函数,名字虽然叫做构造,但他不是用来开空间的,而是来完成初始化工作的。当实例化对象完成后,就会调用构造函数来对成员变量进行初始化。
构造函数的特点:
(1)函数名与类名相同。
(2)无返回值(返回值什么都不写,void也不写)
(3)对象实例化时系统会自动调用构造函数
(4)构造函数可以重载
代码语言:javascript
AI代码解释
class Date
{
public:
//构造函数可以重载
Date()//无参构造函数
{
_year = 1;
_month = 1;
_day = 1;
}
Date(int year,int month,int day)//带参构造函数,全缺省
{
_year = year;
_month = month;
_day = day;
}
void print()
{
cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//调用无参的构造函数
d1.print();
Date d2(2024, 7, 26);//调用带参的构造函数
d2.print();
return 0;
}

(5)如果类中没有显示定义构造函数,那么c++编译器会自动生成一个无参的默认构造函数。
如果类中定义了,编译器将不会再生成。
代码语言:javascript
AI代码解释
class Date
{
public://调用编译器自动生成的构造函数
void print()
{
cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//调用无参的构造函数
d1.print();
return 0;
}

(6)无参构造函数,全缺省构造函数,和我们不写时编译器自动生成构造函数,都叫做默认的构造函数。但这三个函数不能同时存在,不然调用的时候会存在歧义。
说明: c++中,把类型分为内置类型和自定义类型。内置类型就是语言提供的原生数据类型,如int,double等,自定义类型就是我们使用class/struct等关键字自己定义的类型。
(7)我们不写时,编译器自动生成的构造函数,对内置类型成员变量没有要求,是否初始化取决于编译器。而对于自定义类型成员变量,要求调用这个成员变量的默认构造函数,若是没有默认构造函数,编译器就会报错。
3,析构函数
析构函数与构造函数的功能相反,它完成的不是对对象本身的销毁,不如局部对象是存在栈帧的,函数结束栈帧销毁,它就释放了,不需要我们管。c++规定,在对象销毁时,会调用析构函数,完成对象中资源清理释放工作。
析构函数的特点:
(1)析构函数名是在类名前加上~
(2)无参数,无返回值
(3)一个类只能有一个析构函数,若是未显示定义,系统会自动生成默认的析构函数。
(4)对象生命周期结束时,系统会自动调用析构函数。
下面是栈的部分代码:
代码语言:javascript
AI代码解释
typedef int DataType;
class stack
{
public:
//构造函数
stack(size_t capacity=3)
{
//需要开空间
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (_array == nullptr)
{
perror("maloc fail");
return;
}
_size = 0;
_capacity = capacity;
}
~stack()//析构函数
{
//释放资源
if (_array)
{
free(_array);
_array = nullptr;
_size = 0;
_capacity = 0;
}
}
void push(DataType x)
{
_array[_size] = x;
_size++;
}
private:
DataType* _array;
int _size;
int _capacity;
};
int main()
{
stack st;//自动调用构造
st.push(1);
st.push(2);
return 0;//结束调用析构
}
(5)和构造函数类似,我们不写时,编译器自动生成的析构函数对内置类型不做处理,对自定义类型会调用它的默认析构函数。
(6)还有一点,我们显示写了析构函数,对于自定义类型,也会调用它本身的析构,也就是说无论写不写析构函数,自定义类型都会调用它本身的默认析构函数。
对于下面的代码,需要析构自定义类型。就要调用它自己的析构函数。
代码语言:javascript
AI代码解释
class Time
{
public:
~Time()
{
cout << "析构Time" << endl;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
private:
int _year;
int _month;
int _day;
Time _t;//自定义类型
};
int main()
{
Date d1;
return 0;
}

注:先调用的后析构,比如上面的Date类,对象d1,d2,先析构d1,再析构d2.
4,拷贝构造函数
如果一个构造函数的第一个参数是自身类型的引用,且任何额外的参数都有默认值,那么这个构造函数就叫做拷贝构造函数。也就是说,拷贝构造函数是特殊的构造函数。
拷贝构造函数的特点:
(1)拷贝构造函数是构造函数的重载,
(2)拷贝构造函数的第一个参数必须是类类型对象的引用,必须是引用的方式,传值的方式编译器会报错,因为语法逻辑上会引发无穷递归。(理由在后面)
更多推荐


所有评论(0)