为自用学习c++不懂处的笔记
目录
1构造函数和析构函数
作用:
构造函数:自动调用,为类的属性赋值
构析函数:对象销毁前,系统自动调用
语法:
构造与构析函数没有返回值也没有void,直接用类名
例:
class Person
{
public:
//构造函数
Person()
{
cout << "Person的构造函数调用" << endl;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
};
void test01()
{
Person p;//这里实例化后建立了测试函数
}
int main() {
test01();
system("pause");
return 0;
}
2 分类和调用
按照参数分类分为 有参和无参构造 无参又称为默认构造函数 按照类型分类分为 普通构造和拷贝构造
成员函数:
class Person {
public:
//无参(默认)构造函数
Person() {
cout << "无参构造函数!" << endl;
}
//有参构造函数
Person(int a) {
age = a;
cout << "有参构造函数!" << endl;
}
//拷贝构造函数
Person(const Person& p) {
age = p.age;
cout << "拷贝构造函数!" << endl;
}
//析构函数
~Person() {
cout << "析构函数!" << endl;
}
public:
int age;
};
调用:
Person p1(10);//调用有参构造函数
Person p; //调用无参构造函数
//注意不能写Person()其中不添加数字,这是会被认为是一个声明
3拷贝构造函数 (难点)
调用:
Person(const Person& p) {
age = p.age;
cout << "拷贝构造函数!" << endl;
}//p应该是构造函数的地址,他获取了了构造函数的地址中的属性
拷贝构造函数调用时机
* 使用一个已经创建完毕的对象来初始化一个新对象(不采用两个函数的值传递,直接在一个函数内进行传递) * 值传递的方式给函数参数传值() * 以值方式返回局部对象(和值传递的区别在于是写在函数内部)
//1. 使用一个已经创建完毕的对象来初始化一个新对象
void test01() {
Person man(100); //p对象已经创建完毕
Person newman(man); //调用拷贝构造函数
Person newman2 = man; //拷贝构造,应该是隐式用法
//Person newman3;
//newman3 = man; //不是调用拷贝构造函数,赋值操作
}
void doWork(Person p1) {}
void test02() {
Person p; //无参构造函数
doWork(p);
}
Person doWork2()
{
Person p1;
cout << (int *)&p1 << endl;
return p1;
}
void test03()
{
Person p = doWork2();
cout << (int *)&p << endl;
}
4构造函数调用规则
构造函数调用规则如下:
* 如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造
* 如果用户定义拷贝构造函数,c++不会再提供其他构造函数(这里的意思是,提供了拷贝构造函数后,注释掉自己写的有参数构造函数和无参构造函数均显示不存在)
//这里具体要看自己的理解,因为涉及多个逻辑注释
void test02()
{
//如果用户提供有参构造,编译器不会提供默认构造,会提供拷贝构造
Person p1; //此时如果用户自己没有提供默认构造,会出错
Person p2(10); //用户提供的有参
Person p3(p2); //此时如果用户没有提供拷贝构造,编译器会提供
//如果用户提供拷贝构造,编译器不会提供其他构造函数
Person p4; //此时如果用户自己没有提供默认构造,会出错
Person p5(10); //此时如果用户自己没有提供有参,会出错
Person p6(p5); //用户自己提供拷贝构造
}
int main() {
test01();
system("pause");
return 0;
}
```
深拷贝和浅拷贝
浅拷贝:简单的赋值拷贝操作 在指针操作下,构造函数和浅拷贝构造函数指向同一个地址,在构造函数和浅拷贝构造函数下的析构函数会释放两次内存导致出现问题,解决方式是自己写拷贝构造函数 深拷贝:在堆区重新申请空间,进行拷贝操作
如图所示:
``C++
class Person {
public:
//无参(默认)构造函数
Person() {
cout << "无参构造函数!" << endl;
}
//有参构造函数
Person(int age ,int height) {
cout << "有参构造函数!" << endl;
m_age = age;
m_height = new int(height);
}
//拷贝构造函数
Person(const Person& p) {
cout << "拷贝构造函数!" << endl;
//如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
m_age = p.m_age;//浅拷贝
m_height = new int(*p.m_height);//深拷贝,即用new在堆区创建新内存
}
//析构函数
~Person() {
cout << "析构函数!" << endl;
if (m_height != NULL)
{
delete m_height;//由程序员自己释放堆区内存
}
}
public:
int m_age;
int* m_height;
};
void test01()
{
Person p1(18, 180);
Person p2(p1);
cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;
cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
}
int main() {
test01();
system("pause");
return 0;
}
```