1、拷贝构造函数
1、用途
(1)在函数形参是对象,实参传到形参的传递会用到
(2)函数的返回值是对象的时候会用到
2、格式类型
类名(const 类名 &变量名)
3、如果类内部没有写拷贝函数,使用的时候系统会自动添加,但是系统添加的拷贝函数只在值的
复制(浅拷贝),在类中成员有指针的时候会出错。
因此,在类中有指针的时候需要自己写拷贝函数,复制的时候连同堆上的空间一同复制过来(深拷贝)
4、代码
#include <iostream>
using namespace std;
//拷贝构造函数
//1、函数形参有对象的时候,实参传递会用到
//2、对象作为返回值的时候(不同编译器对函数返回值的实现不同可能有不同的影响)
//当类中没有拷贝函数的时候,系统会自动添加(但是添加的是浅拷贝,类中成员没有指针的时候可以使用)
//深拷贝,自己写:复制的时候连同堆上的空间一起复制;
class Test
{
public:
Test(int a,int b,int c)
{
m_a = a;
m_b = b;
m_pa = new int(c);
}
~Test()
{
printf("pa = %p\n",m_pa);
if(m_pa != nullptr)
{
delete m_pa;
m_pa = nullptr;
}
printf("pa = %p\n",m_pa);
}
//拷贝函数
Test(const Test &obj)
{
m_a = obj.m_a;
m_b = obj.m_b;
m_pa = new int;
*m_pa = *(obj.m_pa);
}
void show()
{
cout<<"a = "<<m_a<<",b = "<<m_b<<",*pa = "<<*m_pa<<endl;
}
private:
int m_a;
int m_b;
int *m_pa;
};
int main()
{
Test t(10,20,30);
t.show();
Test t1 = t;
t1.show();
return 0;
}
2、对象初始化
1、有些类型需要在定义的时候赋一个初值,例如const 在c++中是一个常量必须有初值
我们可以在构造函数的后面加上": 初始化对象"进行赋值,成员可以用”,“分隔。
2、对象初始化的一些注意
(1)对象初始化优先于构造函数
(2)对象初始化的顺序与对象在初始化列表中的位置无关,只与变量声明中的位置有关
3、代码
#include <iostream>
using namespace std;
// 对象初始化列表:构造函数后加 : 后面接上要初始化的成员,各个成员之间以逗号进行区分
class Test
{
public:
Test(int a, int b) : m_a(a), m_b(b)
{
printf ("构造: a = %d, b = %d\n", m_a, m_b);
}
~Test()
{
printf ("析构: a = %d, b = %d\n", m_a, m_b);
}
private:
int m_a;
const int m_b;
};
// 1、对象初始化列表的执行要优先于 构造函数
// 2、对象的初始化顺序和对象在初始化列表中所在位置无关,和在类中的声明顺序有关
class Test1
{
public:
Test1(): t1(1,2), t2(2,3)
{
printf ("Test1 的构造函数\n");
}
~Test1()
{
printf ("Test1 的析构函数\n");
}
private:
Test t2;
Test t1;
};
class Test3
{
public:
Test3():m_b(10), m_a(m_b+20)
{
}
Test3(int a)
{
Test3(a, 20);
}
Test3(int a, int b)
{
m_a = a;
m_b = b;
}
void show()
{
printf ("a = %d, b = %d\n", m_a, m_b);
}
private:
int m_a;
int m_b;
};
int main()
{
// Test t(10, 20);
// Test1 t1;
Test3 t;
t.show();
Test3 t2(10);
t2.show();
return 0;
}
3、静态成员
1、c中的static是修饰静态变量的,c++中同样也是,他有一些特性
(1)修饰类中的静态成员变量,该属性不属于某个成员,是类的属性,对所有对象共享
(2)静态成员必须在类的外部初始化
(3)静态成员有两种使用方法
通过变量使用
通过类名使用
(4)静态成员函数中只能包含静态成员变量
2、举例代码
#include <iostream>
using namespace std;
// 类中的 static 的用法
// 1、类的静态成员变量,该属性不属于某个成员,是类的属性,是所有成员所共享的
// 2、静态成员变量必须要在类的外部进行初始化
// 3、静态成员(变量、函数)使用方式:1、通过变量使用 2、通过类名使用
// 4、静态的成员函数 只能使用静态的成员变量
class Test
{
public:
static void show()
{
// printf ("m_a = %d, m_sa = %d", m_a, m_sa);
printf ("m_sa = %d\n", m_sa);
}
public:
int m_a;
int m_b;
static int m_sa;
};
int Test::m_sa = 10;
int main()
{
Test t;
cout << t.m_sa << endl;
Test::m_sa = 20;
cout << t.m_sa << endl;
Test t2;
cout << t2.m_sa << endl;
t2.show();
Test::show();
return 0;
}