一、构造函数
1.构造函数的基本概念
1.对构造函数的理解:
构造函数是类的一种特殊成员函数,其主要功能是在创建对象时进行初始化操作。它的名字与类名相同,并且没有返回值类型(不能是void
)。例如,对于一个名为Rectangle
的类,其构造函数可以写成Rectangle()
或者Rectangle(int width, int height)
等形式。
2.构造函数的调用:
每当创建一个类的对象时,相应的构造函数就会被自动调用。这是 C++ 中对象初始化的重要机制。例如:
class Rectangle {
public:
int width;
int height;
Rectangle() {
width = 0;
height = 0;
}
};
int main() {
Rectangle rect;
// 此时会自动调用Rectangle类的默认构造函数
return 0;
}
2.构造函数的类型
1.默认构造函数
1.定义:
如果一个类没有定义任何构造函数,编译器会自动为这个类生成一个默认构造函数。这个默认构造函数会对对象的基本类型成员进行默认初始化(对于内置类型,如int
、float
等,其值是未定义的;对于类类型成员,会调用其自身的默认构造函数)。
2.自定义默认构造函数:
可以自己定义默认构造函数来明确对象的初始状态。例如:
class Point {
public:
int x;
int y;
Point() : x(0), y(0) {}
};
在这个Point
类中,自定义的默认构造函数将x
和y
都初始化为 0。
2.带参数的构造函数
1.定义:
这种构造函数接受参数,用于根据传入的参数值来初始化对象的成员变量。例如:
class Circle {
public:
double radius;
Circle(double r) : radius(r) {}
};
在这个Circle
类中,构造函数Circle(double r)
接受一个double
类型的参数r
,并将其赋值给成员变量radius
,从而实现根据传入的半径值初始化Circle
对象。
3.拷贝构造函数
1.定义:
用于通过一个已存在的同类型对象来初始化新的对象。它的形式通常是类名(const 类名& 源对象)
。例如:
class String
{
public:
char* data;
String(const String& other)
{
// 假设这里有合理的内存分配和字符串复制操作
int length = strlen(other.data);
data = new char[length + 1];
strcpy(data, other.data);
}
};
当执行String str1; String str2 = str1;
这样的操作时,就会调用拷贝构造函数,将str1
的内容复制到str2
中。注意,这里只是一个简单示例,实际的字符串类还需要考虑内存管理等诸多细节。
2.构造函数的初始化列表
1.定义:
构造函数初始化列表是在构造函数的参数列表和函数体之间,以冒号开始的一系列成员初始化操作。例如:
class Complex
{
public:
double real;
double imag;
Complex(double r, double i) : real(r), imag(i) {}
};
2.优势:
使用初始化列表初始化成员变量通常比在构造函数体内赋值更高效。这是因为对于某些类型(如const
成员变量和引用成员变量),只能通过初始化列表进行初始化。例如:
class ConstExample
{
public:
const int value;
ConstExample(int v) : value(v) {}
};
在这个ConstExample
类中,value
是一个const
成员变量,必须通过初始化列表进行初始化,因为const
成员变量一旦初始化后就不能再被赋值。
4.委托构造函数
1.定义:
委托构造函数是 C++ 11 引入的特性,它允许一个构造函数调用同一个类中的另一个构造函数,以避免代码重复。例如:
class Shape {
public:
int sides;
Shape(int s) : sides(s) {}
Shape() : Shape(0) {}
};
在这个Shape
类中,默认构造函数Shape()
委托给带参数的构造函数Shape(int s)
,将sides
初始化为 0。
5. 转换构造函数
1.定义:
转换构造函数是一种特殊的单参数构造函数,它可以将参数类型隐式或显式地转换为类类型。例如:
class Temperature
{
public:
double value;
Temperature(double v) : value(v) {}
};
int main()
{
double tempValue = 25.0;
Temperature temp(tempValue);
// 或者可以隐式转换(如果允许)
Temperature temp2 = 30.0;
return 0;
}
在这个Temperature
类中,构造函数Temperature(double v)
可以将double
类型的值转换为Temperature
类的对象,既可以像Temperature temp(tempValue)
这样显式转换,也可以在允许隐式转换的情况下像Temperature temp2 = 30.0
这样使用。不过,过度使用隐式转换可能会导致代码的可读性和可维护性变差,需要谨慎使用。
二、析构函数(目前我觉得理解到这部分其实已经够了)
- 析构函数是类的一种特殊成员函数,它的名字是在类名前面加上 “~” 符号。析构函数没有参数,也没有返回值类型。例如,对于类
MyClass
,其析构函数为~MyClass()
。 - 析构函数的主要作用是在对象销毁时执行清理操作,比如释放对象在生命周期内动态分配的内存、关闭文件、释放网络连接等资源。
- 当对象的生命周期结束时,析构函数会自动被调用。
- 例如,对于局部对象,当它所在的函数执行完毕返回时,对象的析构函数就会被调用;
- 对于通过
new
创建的动态对象,当使用delete
删除该对象时,析构函数会被调用。
#include<string>
#include<iostream>
using namespace std;
class Student
{
public:
Student(int n,string nam,string s)//定义有参的构造偶函数
{
num = n;
name = nam;
sex = s;
cout << "构造函数被调用" << endl;//输出有关信息
}
~Student()
{
cout << "析构函数被调用" << endl;//输出有关信息
}
void display()
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "sex:" << sex << endl << endl;
}
private:
int num;
string name;
string sex;
};
int main()
{
Student stud1(10010,"张三","男");//建立对象stu1
stud1.display();
Student stud2(10011,"李华","女");//建立对象stu2
stud2.display();
return 0;
}
程序运行结果: