#include <iostream>
using namespace std;
class Student
{
public:
// 构造函数:在定义对象的时候对 对象进行初始化的函数
// 1、函数名和类名相同
// 2、构造函数没有返回值
// 3、构造是不需要手动调用的,在创建对象的时候编译器自己调用
// 4、构造函数可以被重载
Student() // 无参构造函数
{
_id = 0;
_name = NULL;
cout << "Student() 被调用" << endl;
}
Student(int id)
{
_id = id;
_name = NULL;
cout << "Student(int id) 被调用" << endl;
}
Student(char * name)
{
_id = 0;
_name = name;
cout << "Student(char * name) 被调用" << endl;
}
Student(int id, char *name)
{
_id = id;
_name = name;
cout << "Student(int id, char *name) 被调用" << endl;
}
// 拷贝构造函数:用另一个对象 对当前对象进行初始化
// 类名(const 类名 &变量名)
Student (const Student &obj)
{
_id = obj._id;
_name = obj._name;
cout << "拷贝构造函数被调用" << endl;
}
// 1、~类名
// 2、没有返回值
// 3、没有参数
// 4、不能被重载
~Student()
{
cout << "析构函数被调用" << endl;
}
private:
int _id;
char *_name;
};
// 对象做函数参数传递的时候,会调用拷贝构造函数
// 传引用可以避免拷贝构造函数的调用
// void func(Student s1)
void func(Student &s1)
{
}
Student func1()
{
Student s;
cout << "0000000000000000" << endl;
return s;
}
// 拷贝调用:函数返回值是对象
int main()
{
// 1、不使用函数的返回值
// 函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// 这个匿名对象没人用,所以立马被释放
// func1();
// 2、用新对象去收返回值
// (1)、函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// (2)、将 变量名 s1 给这个匿名对象使用,匿名对象变成了有名对象了
// Student s1 = func1();
// 3、用旧对象去接收返回值
// (1)、函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// (2)、用匿名对象 对 s1 进行赋值!!!!!!!! 不会调用构造函数
// (3)、匿名对象 还是 一个匿名的 所以就被释放
Student s1(10);
s1 = func1(); // 赋值,不会调用 构造函数
cout << "111111111111" << endl;
return 0;
}
// 拷贝调用:对象做函数参数传递的时候
int main4()
{
Student s;
func(s);
return 0;
}
int main3()
{
Student s; // 调用无参构造函数
Student s1(10); // 调用构造函数 Student(int id)
Student s2(s); // 调用拷贝构造函数
Student s3 = s2; // 调用拷贝构造函数 用 s2 对 s3 进行初始化
return 0;
}
int main2()
{
{
cout << "1111111111" << endl;
Student s;
}
cout << "2222222222222222" << endl;
return 0;
}
int main1()
{
Student s;
cout << "1111111111111" << endl;
// 1、括号法
Student s1(1,"小明");
Student s2(2);
// 2、等号法 = 只能调用有一个参数的构造函数
Student s3 = 10; // ====> Student s3(10);
Student s4 = "小红"; // ====> Student s4("小红");
Student s5 = (3,"小红"); // ====> Student s5("小红");
// 3、显示的调用构造函数
Student s6 = Student(3,"小红"); // Student s6(3,"小红");
return 0;
}
using namespace std;
class Student
{
public:
// 构造函数:在定义对象的时候对 对象进行初始化的函数
// 1、函数名和类名相同
// 2、构造函数没有返回值
// 3、构造是不需要手动调用的,在创建对象的时候编译器自己调用
// 4、构造函数可以被重载
Student() // 无参构造函数
{
_id = 0;
_name = NULL;
cout << "Student() 被调用" << endl;
}
Student(int id)
{
_id = id;
_name = NULL;
cout << "Student(int id) 被调用" << endl;
}
Student(char * name)
{
_id = 0;
_name = name;
cout << "Student(char * name) 被调用" << endl;
}
Student(int id, char *name)
{
_id = id;
_name = name;
cout << "Student(int id, char *name) 被调用" << endl;
}
// 拷贝构造函数:用另一个对象 对当前对象进行初始化
// 类名(const 类名 &变量名)
Student (const Student &obj)
{
_id = obj._id;
_name = obj._name;
cout << "拷贝构造函数被调用" << endl;
}
// 编译器默认的拷贝构造 只能复制值,不能复制空间 =====> 浅拷贝
// 深拷贝:进行堆上空间的复制 ----> 自己写拷贝构造函数
class Student
// 如果不是特别需要,不要用一个对象去初始化另一个对象
// 不允许拷贝构造的操作
// 将拷贝构造设成私有的, 声明就可以,不需要实现
// 1、~类名
// 2、没有返回值
// 3、没有参数
// 4、不能被重载
~Student()
{
cout << "析构函数被调用" << endl;
}
private:
int _id;
char *_name;
};
// 对象做函数参数传递的时候,会调用拷贝构造函数
// 传引用可以避免拷贝构造函数的调用
// void func(Student s1)
void func(Student &s1)
{
}
Student func1()
{
Student s;
cout << "0000000000000000" << endl;
return s;
}
// 拷贝调用:函数返回值是对象
int main()
{
// 1、不使用函数的返回值
// 函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// 这个匿名对象没人用,所以立马被释放
// func1();
// 2、用新对象去收返回值
// (1)、函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// (2)、将 变量名 s1 给这个匿名对象使用,匿名对象变成了有名对象了
// Student s1 = func1();
// 3、用旧对象去接收返回值
// (1)、函数返回的时候会产生一个匿名对象,用返回的对象对匿名对象进行初始化,调用拷贝构造函数
// (2)、用匿名对象 对 s1 进行赋值!!!!!!!! 不会调用构造函数
// (3)、匿名对象 还是 一个匿名的 所以就被释放
Student s1(10);
s1 = func1(); // 赋值,不会调用 构造函数
cout << "111111111111" << endl;
return 0;
}
// 拷贝调用:对象做函数参数传递的时候
int main4()
{
Student s;
func(s);
return 0;
}
int main3()
{
Student s; // 调用无参构造函数
Student s1(10); // 调用构造函数 Student(int id)
Student s2(s); // 调用拷贝构造函数
Student s3 = s2; // 调用拷贝构造函数 用 s2 对 s3 进行初始化
return 0;
}
int main2()
{
{
cout << "1111111111" << endl;
Student s;
}
cout << "2222222222222222" << endl;
return 0;
}
int main1()
{
Student s;
cout << "1111111111111" << endl;
// 1、括号法
Student s1(1,"小明");
Student s2(2);
// 2、等号法 = 只能调用有一个参数的构造函数
Student s3 = 10; // ====> Student s3(10);
Student s4 = "小红"; // ====> Student s4("小红");
Student s5 = (3,"小红"); // ====> Student s5("小红");
// 3、显示的调用构造函数
Student s6 = Student(3,"小红"); // Student s6(3,"小红");
return 0;
}