一、构造函数
1、声明:
1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;
语法:ClassName()
2)构造函数在定义时可以有参数;
3)没有任何返回类型的声明。
2、调用
自动调用:一般情况下C++编译器会自动调用构造函数
手动调用:在一些情况下则需要手工调用构造函数
二、析构函数
1、声明:
1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数;
语法:~ClassName()
2)析构函数没有参数也没有任何返回类型的声明;
3)析构函数在对象销毁时自动被调用 。
2、调用
自动调用:一般情况下C++编译器会自动调用构造函数
手动调用:在一些情况下则需要手工调用构造函数
三、代码分析
#include <iostream>
class Test
{
public:
Test() // 构造函数,构造函数与类名相同,没有返回值
{
std::cout << "我是构造函数,被调用了" << std::endl;
}
~Test() // 析构函数,析构函数与类名相同,前面有个~ 不能有返回值和参数
{
std::cout << "我是析构函数,被调用了" << std::endl;
}
};
int main()
{
// 类在创建对象的时候会自动调用构造函数
Test t1;
std::cout << "hello world" << std::endl;
Test *t2 = new Test();
std::cout << "1" << std::endl;
delete t2; // 对象在被销毁的时候会自动调用析构函数
std::cout << "2" << std::endl;
{
Test t3;
}
std::cout << "3" << std::endl;
return 0;
}
四、用途展示
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test() //无参数 构造函数
{
a = 10; //作用完成对属性的初始化工作
p = (char *)malloc(100);
strcpy(p, "aaaaffff");
cout<<"我是构造函数 被执行了"<<endl;
}
void print()
{
cout<<p<<endl;
cout<<a<<endl;
}
~Test() //析构函数
{
if (p != NULL)
{
free(p);
}
cout<<"我是析构函数,被调用了" <<endl;
}
protected:
private:
int a ;
char *p;
};
//给对象搭建一个舞台,研究对象的行为
void objplay()
{
//先创建的对象 后释放
Test t1;
t1.print();
printf("分隔符\n");
Test t2;
t2.print();
}
int main()
{
objplay();
cout<<"hello..."<<endl;
return 0;
}
五、构造函数的分类
1)无参构造函数;2)有参构造函数;
#include <iostream>
using namespace std;
class Test
{
public:
Test() // 无参构造函数
{
m_a = 0;
m_b = 0;
cout << "无参构造函数调用" << endl;
}
Test(int a)
{
m_a = 1;
m_b = 2;
cout << "有参构造函数调用1" << endl;
}
Test(int a, int b) // 有参构造函数
{
m_a = a;
m_b = b;
cout << "有参构造函数调用2" << endl;
}
// 赋值构造函数(拷贝构造函数)
Test(const Test &obj)
{
}
public:
void print()
{
cout << m_a << endl;
}
private:
int m_a;
int m_b;
};
int main()
{
{
//Test t1();
Test t1; // 无参构造函数调用
t1.print();
}
// 有参构造函数调用
{
//1 括号法
Test t1(1);
t1.print();
Test t2(1,2);
t2.print();
//2 等号法
Test t3 = 5; // 只能进行简单的单个元素赋值
Test t4 = (5,6);
//3 直接调用构造函数
Test t5 = Test(8,9);
t5.print();
}
return 0;
}
3)赋值(拷贝)构造函数;
拷贝构造函数的调用时机:
1、Test t2 = t1; // 用对象 t1 去初始化t2
2、Test t2(t0); // 用对象 t0 去初始化t2
3、PrintObj(t0); // 做函数参数的时候
4、t1 = test(); // 函数返回值返回对象
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test() // 无参构造函数
{
m_a = 0;
m_b = 0;
cout << "无参构造函数调用" << endl;
}
Test(int a)
{
m_a = 1;
m_b = 2;
cout << "有参构造函数调用1" << endl;
}
Test(int a, int b) // 有参构造函数
{
m_a = a;
m_b = b;
cout << "有参构造函数调用2" << endl;
}
Test (char *name)
{
strcpy(m_name, name);
}
// 赋值构造函数(拷贝构造函数)
Test(const Test &obj)
{
cout << "拷贝构造函数调用" << endl;
m_a = obj.m_a + 100;
m_b = obj.m_b + 100;
strcpy(m_name, "hello");
}
~Test()
{
cout << "析构函数调用: " << m_name << endl;
}
public:
void print()
{
cout << "m_a:" << m_a << endl;
cout << "m_b:" << m_b << endl;
}
private:
char m_name[20];
int m_a;
int m_b;
};
void PrintObj(Test obj)
{
obj.print();
}
Test test()
{
Test A("name A");
return A;
}
// 赋值构造函数 用一个对象去初始化另一个对象
int main()
{
#if 0
Test t0 = Test(3,4);
Test t1 = Test(5,6);
{
//1 拷贝构造函数调用 1
Test t2 = t1; // 用对象 t1 去初始化t2
t2.print();
}
{
//2 拷贝构造函数调用 2
Test t2(t0); // 用对象 t0 去初始化t2
t2.print();
}
{
//3 类对象当函数形参的时候,实参到形参的转换会调用拷贝构造函数
PrintObj(t0);
}
#endif
{
//4 当函数的返回值是类对象的时候,用一个对象去接收后会调用拷贝构造函数
test();
// 用匿名对象初始化 t, 此时c++编译器直接将匿名对象转化成 t (从匿名转成有名字)
//Test t = test();
Test t1("name t1");
// 用匿名对象给其他对象进行赋值,复制完对象后匿名对象会被析构
t1 = test();
t1.print();
}
return 0;
}
4)默认构造函数:
二个特殊的构造函数
1)默认无参构造函数
当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
2)默认拷贝构造函数
当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制