本篇文章我们来讲一下扩展和聚合类型
1.聚合类型的定义:
在计算机编程中,聚合类型是一种将多个数据元素组合到一个单独的数据结构中的方式。它可以包含不同类型的数据,并且这些数据可以按照特定的顺序或规则进行组织。
常见的聚合类型有数组、结构体和类等。下面简要介绍一些常见的聚合类型:
- 数组(Array):数组是相同类型元素的集合,通过索引访问其中的元素。
- 结构体(Struct):结构体是用户自定义的复合数据类型,可以包含不同类型的成员变量,通过点运算符访问各个成员。
- 类(Class):类也是用户自定义的复合数据类型,类似于结构体,但可以包含方法和属性,并支持继承和封装等面向对象特性。
- 枚举(Enumeration):枚举是一种有限集合值列表,用于表示一组相关常量。每个枚举值都有一个与之关联的整数或字符值。
- 联合体(Union):联合体允许在相同内存位置存储不同类型的变量,但只能同时使用其中一种。
这些聚合类型可根据需要灵活地组织和管理数据,在程序设计中起着重要作用。
下面我们来看一下聚合类型的新定义 C++17及以上
聚合类型所需要的条件
1.没有用户提供的构造函数(如果是基类派生出派生类的话 则派生类可以有构造函数)
2.没有私有和受保护的非静态数据成员
3.没有虚函数
如果类涉及到继承 额外满足条件:
1.必须是公开的基类 不能是私有或者是受保护的基类
2.不能是虚继承
基类是非聚合类型的情况下 派生类也可能是聚合类型
代码实例:
#include <iostream> class Base { public: int x; }; struct Derived : public Base { int y; }; int main() { Derived d{1, 2}; std::cout << "Derived - x: " << d.x << ", y: " << d.y << std::endl; return 0; }
禁止聚合类型使用用户声明的构造函数 尤其是显示制定默认或者显示删除构造函数也都是不行
代码实例:
#include <iostream> using namespace std; struct X { X() = default; }; struct Y { Y() = delete; };
以上代码这两个结构体都是非聚合类型的结构体
1 结构体显示的指定了编译器生成的默认构造函数
2结构体显示的删除了默认构造函数 这些都是不认可的
使用小括号的列表初始化聚合类型对象
在C++17之前 使用()初始化聚合类型是不可以的 因为之前小括号初始化会默认优先查找构造函数而不是 但是在C++17以后 可以采用小括号初始化
看一下代码实例:
#include <iostream> using namespace std; struct X { int i; float f; }; int main() { ;;; X x{ 10,7.0f }; X c(10, 5.0f); return 0; }
注意 小括号的初始化支持缩窄转换
最后 介绍一下C++ is_aggregate_v这个函数
is_aggregate_v
是一个C++模板元编程中的特性,用于判断给定的类型是否是一个聚合类型(aggregate type)。它是在C++17标准中引入的。这个特性可以通过std::is_aggregate
类模板来实现。
代码实例:
#include <iostream> #include <type_traits> struct Point { int x; int y; }; struct Person { std::string name; int age; }; int main() { std::cout << std::boolalpha; std::cout << std::is_aggregate_v<Point> << "\n"; // 输出 true std::cout << std::is_aggregate_v<Person> << "\n"; // 输出 false return 0; }
Point是聚合类型
Person不是聚合类型
std::string 是一个复杂类型,它具有自己的默认构造函数和析构函数,并且需要进行动态内存管理。按照C++标准规定,如果一个结构体拥有任何非静态数据成员需要进行默认初始化,则该结构体不再符合聚合类型定义。
好了 本篇文章就到这里
在这里小编想给大家推荐一个课程: