1.构建函数和析构函数
构造函数:
类名(....){} 可以有参数 无返回值 可以重载 在对象创建时系统自动调用一次
析构函数:
~类名() {} 不可以有参数 无返回值 不能重载 对象销毁前系统自动调用一次
#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "构造函数" << endl;
}
~Person()
{
cout << "析构函数" << endl;
}
};
int main()
{
Person p;
}
2.构造函数的分类和调用
构造函数可以分为普通构造和拷贝构造
普通构造又可以分为有参构造和无参构造
当然调用也有三种方法
括号法 显示法 隐式转化法
直接上代码
#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "无参函数" << endl;
}
Person(int)
{
cout << "有参构造" << endl;
}
Person(const Person & p)
{
cout << "拷贝构造" << endl;
}
~Person()
{
cout << "析构函数" << endl;
}
};
int main()
{
//括号法
Person p1;
Person p2(10);
Person p3(p2);
//显示法
Person p4 = Person();
Person p5 = Person(10);
Person p6 = Person(p5);
//隐式
Person p7;
Person p8 = 10;
Person p9 = p8;
Person();//匿名对象,行结束后释放对象
cout << "hahaha" << endl;
}
注意:1 利用无参构造创建对象不要加()因为系统会看成一个函数声明 Person p1();
2 不要利用拷贝构造创建匿名对象 因为 Person (p)----- Person p 会看成创建无参构造对象
3.拷贝构造函数调用时机
这个也比较容易理解 主要是要清楚 值传递的规则
一般拷贝构造函数调用有三种情况
1.使用一个已经创建完的对象创建新的对象
2.值传递的方式给函数参数传值
3.以值方式返回局部对象
值传递是会创建一个新的对象空间 也会在作用域结束后销毁
第一种情况上面已经说明就不写了
上代码
#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "默认构造" << endl;
}
Person(const Person& p)
{
cout << "拷贝构造" << endl;
}
~Person()
{
cout << "析构" << endl;
}
};
void test(Person p)
{
}
Person text()
{
Person p;
return p;
}
int main()
{
Person p;
test(p);
text();//最好接收一下
}
4.构造函数调用规则
这个很简单,注意用法就行了
1.如果用户定义了有参构造函数,C++就不提供默认构造函数,但提供拷贝构造函数
2.如果用户定义了拷贝构造函数(浅拷贝),就都不提供了
5.深拷贝和浅拷贝
如果用户没有定义拷贝函数,那么C++会提供一个,但是只会浅拷贝
浅拷贝是简单的值拷贝,当属性有在堆区开辟的,必须要用深拷贝,不然会程序会崩掉
代码如下
#include <iostream>
using namespace std;
class Person
{
public:
Person(int a)//在堆区开辟空间
{
height =new int(a);
}
Person(const Person& p) //拷贝时默认是浅拷贝,需重新申请一段空间
{
height = new int (*p.height);
}
~Person()
{
if (height != NULL)
{
delete(height);
height = NULL;
}
cout << "析构" << endl;
}
int* height;
};
int main()
{
Person p(100);
Person p1(p);
cout << *p.height << endl;
cout << *p1.height << endl;
}
图示两种拷贝的区别
6.初始化列表。.....
这个也非常简单 换了一种赋值的方式
Person(int a,int b,int c): m_A=a,m_B=b,m_C=C
{
}
---------------------------------------------------------------------------------
Person(int a,int b,int c)
{
m_A=a;
m_B=b;
m_C=c;
}
两种赋值方式等价
7.类对象作为类成员
当其他类对象作为本类成员,先构造其他类对象,再构造本身
析构顺序相反
代码
#include <iostream>
using namespace std;
//类对象作类成员
class Lover
{
public:
Lover(string name) :m_name(name) //初始化对象列表
{
}
string m_name;
};
class Person
{
public:
//Lover L =lover
//这个就是隐式转换 创建一个对象 有参构造
Person(string name, string lover) :n_name(name), L(lover)
{
}
string n_name;
Lover L;
};
int main()
{
Person p("猴","猿");
cout << p.n_name << endl;
cout<<p.L.m_name;
}
8.静态成员
首先成员嘛,所以出现在类中
静态成员变量:
编译阶段就分配空间,类内声明,类外初始化,所有对象共享这份数据
可以通过对象,或者直接通过类名访问这个变量(public 下的)
class Person
{
public :
static int m;
}
int Person:: m=10;
访问两种方式
1.Person p
p.m
2.Person::m
静态成员函数:
所有对象共享一个函数
静态成员函数只能访问静态成员变量(public 下的)
抓住共享就知道,不能访问非静态成员变量
因为非静态成员变量属于特定对象