Struct&Class的默认赋值(复制)方式

本文通过示例代码详细解析了 C++ 中结构体(Struct)的默认赋值行为,强调了当结构体包含指针成员时可能出现的问题及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Struct和Class的默认赋值方式是由编译器提供的,并且这种赋值方式是标准里规定好的。

 

Struct和Class的默认赋值方式是一样的,所以这里我就以Struct来进行简单说明:

Struct的赋值,就是一个一个成员进行值的copy。

 

基于这样的实现方式,一般情况下没有问题,但是,成员是指针的时候,就要格外小心了。

原因如下:

=======================================

指针pA指向A空间
指针pB指向B空间

pA=pB
pA也指向了B空间

这里在释放pA指向的空间,就是把B空间释放了

如果B空间我们是不想释放的,那么就会出问题。

因为,当B空间释放后,系统会将这个空间收回,再利用。

所以,等到我们再次释放pB指向的空间的时候(B空间),程序就会崩溃。

 

这也是c++中说的:

一般如果构造函数里面为裸指针分配了空间的话,都必须重写拷贝构造函数和赋值函数

=======================================

下面这段代码是验证Struct赋值的。

 

#include <stdio.h>
#include <stdlib.h>

typedef struct dataItem
{
        int m_Item1;
        int m_Item2;
        char *m_Item3;
}Item;

Item g_dataItem={3,4,"g_dataItem"};
Item ga_dataItem[2]={
	 {5,6,"ga_dataItem[1]"},
	 {7,8,"ga_dataItem[2]"}
	 };

void changeItem(Item *pdataItem);
void changeItem2(Item *pdataItem);

main()
{
      Item dataItem;

      dataItem.m_Item1 = 1;
      dataItem.m_Item2 = 2;
      dataItem.m_Item3 = "dataItem";
      
      printf("dataItem address=%x\n",&dataItem);
      printf("\n");
      
      printf("g_dataItem address:%x\n",&g_dataItem);
      printf("\n");
       
      printf("ga_dataItem address:%x\n",ga_dataItem);
 	  printf("ga_dataItem[0] address:%x\n",&ga_dataItem[0]);
 	  printf("ga_dataItem[1] address:%x\n",&ga_dataItem[1]);
      
      printf("\n********************************\n");
      
      printf("dataItem address:%x\n",&dataItem);
      printf("\n");
      
      changeItem(&dataItem);
      printf("m_Item1=%d\n",dataItem.m_Item1);
      printf("m_Item2=%d\n",dataItem.m_Item2);
      printf("m_Item3=%s\n",dataItem.m_Item3);
      printf("\n\n");
      
      changeItem2(&dataItem);
      printf("m_Item1=%d\n",dataItem.m_Item1);
      printf("m_Item2=%d\n",dataItem.m_Item2);
      printf("m_Item3=%s\n",dataItem.m_Item3);

	  printf("\n********************************\n");      
      system("pause");
}

void changeItem(Item *pdataItem)
{
 	  printf("@changeItem function\n");
	  printf("pdataItem:%x\n",pdataItem);
 	  printf("&g_dataItem:%x\n",&g_dataItem);
 	  printf("\n");
	  *pdataItem = g_dataItem;
	  
}

void changeItem2(Item *pdataItem)
{
 	  printf("@changeItem2 function\n");
	  printf("pdataItem:%x\n",pdataItem);
 	  printf("&g_dataItem:%x\n",&ga_dataItem[1]);
 	  printf("\n");
	  *pdataItem = ga_dataItem[1];
	  
}


输出如下:

dataItem address=22ff60

g_dataItem address:402000

ga_dataItem address:40200c
ga_dataItem[0] address:40200c
ga_dataItem[1] address:402018

********************************
dataItem address:22ff60

@changeItem function
pdataItem:22ff60
&g_dataItem:402000

m_Item1=3
m_Item2=4
m_Item3=g_dataItem


@changeItem2 function
pdataItem:22ff60
&g_dataItem:402018

m_Item1=7
m_Item2=8
m_Item3=ga_dataItem[2]

********************************
请按任意键继续. . .

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值