C++的构造函数,c++ 结构体 构造函数
C构造函数的知识在各种C教材中都有介绍,但初学者往往不太注意观察和总结各种构造函数的特点和用法。所以我根据自己的C编程经验,总结了C中各种构造函数的特点,并附上例子,希望对初学者有所帮助。
C类构造函数详解
首先,构造函数是做什么的?
班级
计数器
公众的
//类计数器的构造函数
//特点:类名作为函数名,没有返回类型。
计数器()
{
m _ value=0;
}
私人的
//数据成员
m _ value
创建类对象时,编译系统对象分配内存空间,自动调用构造函数——构造函数完成成员初始化。
例如:计数器C1;
系统为对象c1的每个数据成员(m_value)分配内存空间,调用构造函数Counter()自动将对象c1的m_value初始化为0。
构造函数初始化一个对象的数据成员。
第二,构造函数的类型
班级
复杂的
{
私人的
:
两倍
m _ real
两倍
m _ imag
公众的
//没有参数构造函数
//如果创建一个类,没有写任何构造函数,系统会自动生成默认的无参数构造函数,这个构造函数是空的,什么都不做。
//只要你写了下面的一个构造函数,系统就不会自动生成这样的默认构造函数。想要有这样一个无参数的构造函数,需要自己写。
复杂(
空的
{
m _ real=0.0
m _ imag=0.0
}
//通用构造函数(也称为重载构造函数)
//一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的数量或类型不同(基于C的重载函数原理)
//比如:也可以写一个Complex( int num)的构造函数
//创建对象时,根据传入的不同参数调用不同的构造函数。
复杂(
两倍
真实的,
两倍
imag)
{
m _ real=real
m _ imag=imag
}
//复制构造函数(也称为复制构造函数)
//复制构造函数参数是指类对象本身,用来根据已有的对象复制这个类的一个新对象。通常,现有对象的数据成员的值将被复制到函数中新创建的对象。
//如果没有显示写复制构造函数,系统默认会创建一个复制构造函数。但是,当类中有指针成员时,默认情况下创建此复制构造函数会有风险。具体原因请查阅“轻抄”和“深抄”的文章。
复杂(
常数
复合体c)
{
//复制对象c中的数据成员值。
m _ real=c.m _ real
m _ img=c.m _ img
}
//类型转换构造函数根据指定类型的对象创建该类的对象。
//例如:下面将基于double类型的对象创建一个复杂对象
复杂:复杂(
两倍
r)
{
m _ real=r;
m _ imag=0.0
}
//等号运算符重载
//注意,这个类似的复制构造函数将=右边的这个类对象的值复制到等号左边的对象。它不属于构造函数,等号左右两边的对象必须已经创建。
//如果没有显示write=operator重载,系统也会创建一个default=operator重载,只做一些基本的复制工作。
复杂的
操作员
=(
常数
复杂rhs)
{
//首先检查等号右边的对象书是否是左边的对象书。如果是对象本身,就直接返回。
(
这
==rhs)
{
返回
*
这
}
//将等号右边的成员复制到左边的对象中。
这
-m _ real=RHS . m _ real;
这
-m _ imag=RHS . m _ imag;
//再次传递等号左边的对象
//目的是支持连续eg:a=b=c系统先运行b=c。
//然后运行A=(B=C的返回值,这里应该是复制C值后的B对象)
返回
*
这
}
使用上面定义的类对象来说明每个构造函数的用法:
空的
主()
//调用无参数构造函数,数据成员初始值设置为0.0。
复合体c1、C2;
//调用通用构造函数,将数据成员的初始值赋给指定值
复杂c3(1.0,2.5);
//您也可以使用以下形式
复数c3=复数(1.0,2.5);
//将c3的数据成员的值赋给c1
//由于事先已经创建了c1,所以这里不会调用任何构造函数
//只会调用=运算符重载函数
c1=c3
//调用类型转换构造函数
//系统首先调用类型转换构造函数创建5.2作为该类的临时对象,然后调用等号运算符重载将临时对象赋给c1。
c2=5.2
//调用复制构造函数(有两种方法调用)
复合物C5(C2);
复杂c4=c2
//注意重载和=运算符的区别。这里等号左边的对象没有提前创建,需要调用复制构造函数,参数是c2。
第三,思考和测试
1.仔细观察复制构造函数。
复杂(
常数
复合体c)
{
//复制对象c中的数据成员值。
m _ real=c.m _ real
m _ img=c.m _ img
}
为什么可以在函数中直接访问对象C的私有成员?
2.挑战问题以理解引用值和传递值之间的区别。
复杂测试1(
常数
复合体c)
{
返回
c;
}
复杂测试2(
常数
复合体c)
{
返回
c;
}
复杂测试3()
{
静电
复杂c(1.0,5.0);
返回
c;
}
复杂测试4()
{
静电
复杂c(1.0,5.0);
返回
c;
}
空的
主()
{
复合体a,b;
//在执行以下函数的过程中,会多次调用构造函数。叫什么构造函数?
测试1(a);
测试2(a);
b=test3();
b=test 4();
test 2(1.2);
//下面的语句会出错吗?
test1(1.2);
//那么//test1(复数(1.2))呢?
}
四。附录(浅拷贝和深拷贝)
如上所述,如果没有自定义的复制构造函数,系统会创建默认的复制构造函数,但系统创建的默认复制构造函数只会进行“浅层复制”,即被复制对象的数据成员的值会被逐个赋给新创建的对象。如果这个类的数据成员中有指针成员,那么新对象的指针所指向的地址将与被复制对象的地址相同,删除这个指针将导致两次重复删除和错误。下面是一个例子:
[浅拷贝和深拷贝]
#包含iostream.h
#包括
线
班级
人
公众的
:
//构造函数
人(
茶
* pN)
{
标准输出
调用了通用构造函数!\n
m_pName=
茶
[strlen(pN)1];
//在堆中打开一个内存块存储pN指向的字符串
(m_pName!=空)
{
//如果m_pName不是空指针,则将参数指针pN指向的字符串复制给它。
strcpy(m_pName,pN);
}
}
//系统创建的默认复制构造函数只复制位模式。
人(人p)
{
//使两个字符串指针指向同一个地址位置
m _ pName=p.m _ pName
}
~人( )
{
删除m _ pName
}
私人的
:
茶
* m _ pName
空的
主( )
{
人男子(
路军
Person女(男);
//结果,男人和女人的指针都指向同一个地址
//当函数结束析构时
//同一个地址被删除两次
//接下来我自己设计复制构造函数实现“深度复制”,也就是不希望指针指向同一个地址,而是为新对象的指针数据成员重新申请一块内存。
人(人CHS);
//用运算符new为新对象的指针数据成员分配空间
m_pName=
茶
[strlen(p . m _ pName)1];
(m_pName)
{
//复制内容
strcpy(m_pName,CHS . m _ pName);
}
//新创建对象的m_pName和原对象chs的m_pName不再指向同一个地址。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。