构造和析构必须要声明在全局作用域
构造函数
- 没有返回值 不用写void
- 函数名 与 类名相同
- 可以有参数 ,可以发生重载
- 构造函数 由编译器自动调用一次 无须手动调用
析构函数
- 没有返回值 不用写void
- 函数名 与类名相同 函数名前 加 ~
- 不可以有参数 ,不可以发生重载
- 析构函数 也是由编译器自动调用一次,无须手动调用
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public: //构造和析构必须要声明在全局作用域
//构造函数
//没有返回值 不用写void
//函数名 与 类名相同
//可以有参数 ,可以发生重载
//构造函数 由编译器自动调用一次 无须手动调用
Person()
{
cout << "Person的构造函数调用" << endl;
}
//析构函数
//没有返回值 不用写void
//函数名 与类名相同 函数名前 加 ~
//不可以有参数 ,不可以发生重载
//析构函数 也是由编译器自动调用一次,无须手动调用
~Person()
{
cout << "Person的析构函数调用" << endl;
}
};
void test01()
{
Person p;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
构造函数知识点
括号法构造函数
- 不能用括号法 调用无参构造函数 Person p3(); 编译器认为代码是函数的声明
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//构造函数分类
//按照参数分类: 无参构造(默认构造函数) 和 有参构造
//按照类型分类: 普通构造函数 拷贝构造函数
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//复制构造函数
Person(const Person &p )
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
private:
int m_Age{0};
};
//构造函数的调用
void test01()
{
Person p;
//括号法
Person p1(10);
Person p2(p);
}
int main(){
test01();
//Person p(18);
//Person p2(p);
//cout << "p2的年龄: " << p2.m_Age << endl;
system("pause");
return EXIT_SUCCESS;
}
显示构造法
- Person(10); //匿名对象 特点: 当前行执行完后 立即释放
- 不要用拷贝构造函数 初始化 匿名对象 Person(p3); 编译器认为 Person p3对象实例化 如果已经有p3 p3就重定义
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//构造函数分类
//按照参数分类: 无参构造(默认构造函数) 和 有参构造
//按照类型分类: 普通构造函数 拷贝构造函数
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//复制构造函数
Person(const Person &p )
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
private:
int m_Age{0};
};
//构造函数的调用
void test01()
{
//显示法
Person p3 = Person(10); //有参构造
Person p4 = Person(p3); //拷贝构造
}
int main(){
test01();
//Person p(18);
//Person p2(p);
//cout << "p2的年龄: " << p2.m_Age << endl;
system("pause");
return EXIT_SUCCESS;
}
隐式构造
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//构造函数分类
//按照参数分类: 无参构造(默认构造函数) 和 有参构造
//按照类型分类: 普通构造函数 拷贝构造函数
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//复制构造函数
Person(const Person &p )
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
private:
int m_Age{0};
};
//构造函数的调用
void test01()
{
//隐式法
Person p5 = 10; //Person p5 = Person(10);
Person p6 = p5;
}
int main(){
test01();
//Person p(18);
//Person p2(p);
//cout << "p2的年龄: " << p2.m_Age << endl;
system("pause");
return EXIT_SUCCESS;
}
复制构造函数调用时机
1、用已经创建好的对象来初始化新的对象
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//拷贝构造函数
Person(const Person &p)
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
int m_Age;
//1、用已经创建好的对象来初始化新的对象
void test01()
{
Person p1(18);
Person p2 = Person(p1);
cout << "p2的年龄:" << p2.m_Age<< endl;
}
};
int main(){
test01();
// test02();
// test03();
system("pause");
return EXIT_SUCCESS;
}
2、值传递的方式 给函数参数传值
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//拷贝构造函数
Person(const Person &p)
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
int m_Age;
};
//值传递的方式 给函数参数传值
void doWork(Person p)
{
}
void test02()
{
Person p1(100);
doWork(p1);
}
int main(){
// test01();
test02();
// test03();
system("pause");
return EXIT_SUCCESS;
}
3. 以值方式 返回局部对象
- 在有些编译环境下,上面运行结果可能不尽相同,因为编译器有时会针对复制构造函数的调用做优化,避免不必要的复制构造函数的调用。故这里本应该有复制构造函数的调用的,但由于编译器进行了优化,没有调用复制构造函数。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//拷贝构造函数
Person(const Person &p)
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
int m_Age;
};
Person doWork2()
{
Person p;
return p;
}
void test03()
{
Person p = doWork2();
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "Person的有参构造函数调用" << endl;
}
//拷贝构造函数
Person(const Person &p)
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
//析构函数
~Person()
{
cout << "Person的析构函数调用" << endl;
}
int m_Age;
};
Person doWork2()
{
Person p{2});
return p;
}
void test03()
{
Person p = doWork2();
}
构造函数的调用规则
- 编译器会给一个类 至少添加3个函数 默认构造(空实现) 析构函数(空实现) 拷贝构造(值拷贝)
- 如果我们自己提供了 有参构造函数,编译器就不会提供默认构造函数,但是依然会提供拷贝构造函数
- 如果我们自己提供了 拷贝构造函数,编译器就不会提供其他构造函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "有参构造函数调用" << endl;
}
Person(const Person &p)
{
m_Age = p.m_Age;
cout << "拷贝构造函数调用" << endl;
}
~Person()
{
cout << "析构函数调用" << endl;
}
int m_Age;
};
void test01()
{
Person p1;//提供拷贝构造后,要自己提供默认构造,否则出错
p1.m_Age = 20;
Person p3(29);
Person p2(p1);
Person p4(p3);
cout << "p2的年龄为: " << p2.m_Age << endl;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}