C++基础知识整理六(new delete 结构体 共用体)

本文详细梳理了C++中new和delete的使用,包括如何动态分配和释放内存。同时,深入讨论了结构体和共用体的概念,通过实例展示了它们在程序中的应用和操作结果。

1,new和delete

使用运算符new动态开辟空间:

#include "pch.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
	int n ;
	int *p ;
	int sum =0 ;
	cout<<"请输入班级的人数";
	cin>>n;	
	p = new int[n] ;
	
	if(!p)//如果动态开辟内存空间失败
	{
		return 1;
	}		
	cout<<"请输入数学的成绩";
	for(int i=0;i<n;i++)
	{
		cin>>p[i];
	}
	for(int i=0;i<n;i++)
	{
	sum = sum+ p[i];
	}
	cout<<"平均值为:"<<sum/n;
	
	return 0;
}

运行结果为:

#include "pch.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
<think>好的,用户想了解如何在C++中使用结构体嵌套共用体,并结合vector实现增加、删除和修改操作。首先,我需要回忆结构体共用体的基本用法。结构体可以包含多个不同类型的成员,而共用体在同一时间只能存储其中一个成员,这样可以节省内存。 接下来,用户提到要嵌套在结构体中,所以可能需要一个结构体包含共用体作为其成员。同时,结合vector,应该是要用vector来管理这些结构体实例,实现增删改查的操作。 首先,考虑如何定义结构体共用体。例如,定义一个共用体,里面可能有不同的数据类型,比如int、double和字符串。然后结构体包含这个共用体一个类型标记,用来记录当前共用体中存储的是哪种类型的数据。 然后,如何将这些结构体对象存储在vector中。可能需要一个vector的元素类型是该结构体类型。这样,就可以通过vector的方法进行添加、删除和修改操作。 添加操作应该是向vector末尾push_back新的结构体实例。删除可能需要查找特定元素,然后使用erase方法。修改的话,可以通过索引访问vector中的元素,然后更改其共用体的值和类型标记。 需要注意的是,使用共用体时,必须确保访问的是当前活动的成员,否则会导致未定义行为。因此,类型标记非常重要,每次修改共用体值时都要更新标记。 另外,C++中的共用体C++11之后可以包含有非平凡构造函数的类型,比如std::string,但需要手动管理构造和析构。这可能带来复杂性,所以在示例中可能需要简化,比如使用C风格的字符串(char数组)或者限制类型。不过,用户可能希望使用更现代的方法,所以可能需要包含string,并正确处理内存。 不过,考虑到用户提供的引用中提到了模板特化和构造函数的相关内容,比如引用[1]中的结构体B的构造函数,引用[2]中的模板特化处理const char*,引用[3]提到C++新旧版本的不兼容性,比如new的行为变化。所以在实现时需要注意C++的版本特性,比如使用C++11或更高版本,以便在共用体中使用string等类型,并正确管理资源。 可能需要给出一个示例代码,定义结构体包含共用体,然后使用vector管理这些结构体。然后演示如何添加、删除和修改元素。在删除时,要注意vector的erase方法会导致迭代器失效,所以需要使用正确的循环方式,比如使用erase返回的新的迭代器。 此外,用户的问题是关于结构体嵌套共用体,所以需要确保语法正确。例如,结构体内部定义共用体,或者共用体作为结构体的成员。可能需要使用匿名共用体或者命名共用体,并结合类型标签来区分当前存储的数据类型。 可能还需要考虑如何输出或显示vector中的元素,方便验证操作是否正确。比如重载<<运算符,或者编写打印函数,根据类型标签输出对应的值。 总结步骤: 1. 定义共用体,包含不同类型的数据成员,可能需要支持int、double、string等。 2. 定义结构体,包含共用体一个类型标签(enum)。 3. 使用vector存储该结构体的实例。 4. 实现添加操作:创建结构体实例,设置类型标签和共用体值,push_back到vector。 5. 实现删除操作:根据索引或条件,使用erase方法。 6. 实现修改操作:通过索引访问元素,更新类型标签和共用体值。 7. 注意资源管理,特别是string的构造和析构,可能需要手动调用析构函数,或者使用C++17的std::variant替代共用体以简化代码。 不过,用户明确要求使用结构体嵌套共用体,所以可能需要使用传统方法,而不是variant。因此,在示例代码中需要正确处理这些细节,比如在修改共用体成员时,先销毁原来的对象,再构造新的对象。 另外,用户提供的引用[2]中的模板特化处理const char*,可能相关于如何在共用体中处理字符串。可能需要使用char数组或者const char*,或者正确管理std::string的生命周期。 因此,在示例中,可能选择在共用体中使用std::string,但需要注意在C++中,只有当编译器支持C++11或更高版本时,才能在共用体中包含有非平凡构造函数的类型。需要确保在修改时正确调用析构函数和构造函数。 例如,当更改共用体的类型时,如果之前存储的是string,需要先调用其析构函数,再构造新的类型。这可能比较复杂,所以在示例代码中,可能需要简化处理,或者使用一个辅助函数来安全地设置值。 综上,需要构建一个示例,展示结构体嵌套共用体,结合vector的增删改操作,并处理类型安全的问题。同时,代码需要符合C++标准,并注意资源管理。</think>在C++中,结构体嵌套共用体并结合vector操作可通过以下步骤实现: ### 一、基础定义 ```cpp #include <vector> #include <string> #include <iostream> // 定义数据类型枚举 enum DataType { INT, DOUBLE, STRING }; struct VariantStruct { DataType type; // 类型标识符 union Value { // 嵌套匿名共用体 int int_val; double double_val; std::string str_val; Value() {} // 需要自定义构造函数 ~Value() {} // 需要自定义析构函数 } value; // 构造函数需要手动管理内存 VariantStruct() : type(INT) { new(&value.int_val) int(0); } ~VariantStruct() { if (type == STRING) value.str_val.~basic_string(); } }; ``` ### 二、Vector容器操作 ```cpp std::vector<VariantStruct> vec; // 添加操作 void add_element(DataType t, const void* data) { VariantStruct vs; vs.type = t; switch(t) { case INT: vs.value.int_val = *static_cast<const int*>(data); break; case DOUBLE: vs.value.double_val = *static_cast<const double*>(data); break; case STRING: new(&vs.value.str_val) std::string(*static_cast<const std::string*>(data)); break; } vec.push_back(vs); } // 删除操作 void delete_element(size_t index) { if (index < vec.size()) { if (vec[index].type == STRING) vec[index].value.str_val.~basic_string(); vec.erase(vec.begin() + index); } } // 修改操作 void modify_element(size_t index, DataType new_type, const void* new_data) { if (index >= vec.size()) return; auto& elem = vec[index]; if (elem.type == STRING) elem.value.str_val.~basic_string(); elem.type = new_type; switch(new_type) { case INT: new(&elem.value.int_val) int(*static_cast<const int*>(new_data)); break; case DOUBLE: new(&elem.value.double_val) double(*static_cast<const double*>(new_data)); break; case STRING: new(&elem.value.str_val) std::string(*static_cast<const std::string*>(new_data)); break; } } ``` ### 三、使用示例 ```cpp int main() { add_element(INT, new int(42)); add_element(STRING, new std::string("hello")); modify_element(0, DOUBLE, new double(3.14)); delete_element(1); // 删除字符串元素 } ``` ### 关键点说明 1. **placement new/delete**:必须显式调用构造函数和析构函数来管理非平凡类型(如std::string)[^1] 2. **类型安全**:通过枚举类型标识保证数据访问的正确性 3. **内存管理**:vector会自动管理结构体内存,但共用体成员需要手动处理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值