C++ | C++数据结构

C/C++ 数组允许定义可存储相同类型数据项的变量,但是结构是 C++ 中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

​C++​​​ 中保留了C语言的 ​​struct​​​ 关键字,并且加以扩充。在C语言中,​​struct​​​ 只能包含成员变量,不能包含成员函数。而在C++中,​​struct​​​ 类似于 ​​class​​,既可以包含成员变量,又可以包含成员函数。

C++中的 ​​struct​​​ 和 ​​class​​ 基本是通用的,唯有几个细节不同:

  • 使用 ​​class​​​ 时,类中的成员默认都是 ​​private​​​ 属性的;而使用 ​​struct​​​ 时,结构体中的成员默认都是 ​​public​​ 属性的。
  • ​class​​​ 继承默认是 ​​private​​​ 继承,而 ​​struct​​​ 继承默认是 ​​public​​​ 继承(《​​C++继承与派生​​》一章会讲解继承)。
  • ​class​​​ 可以使用模板,而 ​​struct​​​ 不能(《​​模板、字符串和异常​​》一章会讲解模板)。

定义结构

为了定义结构,您必须使用 ​struct​​ 语句。​​struct​​​ 语句定义了一个包含多个成员的新的数据类型,​​struct​​ 语句的格式如下:

struct type_name{
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
...
}object_names;

实例1

/*******************************************************************
* > File Name: cplusplus-struct.cpp
* > Create Time: 2021年09月26日 17:02:31
******************************************************************/
#include <iostream>
using namespace std;

struct c_plus_struct{
int a; //成员变量
int b; //成员变量

c_plus_struct(int m, int n){ // 构造函数:初始化成员变量
a = m;
b = n;
}
};

int main(int argc, char* argv[])
{
c_plus_struct cpS = c_plus_struct(12, 13);

cout << "a = " << cpS.a << endl;
cout << "b = " << cpS.b << endl;

return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day19> vim cplusplus-struct.cpp
PS E:\fly-prj\cplusplus\day19> make
g++ -o cplusplus-struct cplusplus-struct.cpp -g -Wall -std=c++11 -lpthread
PS E:\fly-prj\cplusplus\day19> .\cplusplus-struct.exe
a = 12
b = 13

C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不要​​void​​关键字,这样的方法就是构造器的初始化方法。

struct MediaEvent
{
eMediaEvents evID; /**< Event type identifier*/
int priority; /**< Event priority, defined by eMediaEventPriority enum*/
u_int32_t index; /**< Set by Media Framework for event object identification*/

char* payload; /**< Media event owns payload, so payload to have only trivial destructor.
This payload is processed by Serializer and Deserializer helpers.*/
size_t payloadSize; /**< Payload size in bytes, used by deserializer. */

//initialization and cleanup
MediaEvent() : evID (MEDIAE_START), priority(0), index(0), payload(nullptr), payloadSize(0) {}
~MediaEvent() { delete [] payload;}

//make it non copyable and non moveable
//force to use heap
MediaEvent(const MediaEvent&) = delete;
MediaEvent(const MediaEvent&&) = delete;
MediaEvent& operator = (const MediaEvent&) = delete;
MediaEvent& operator = (const MediaEvent&&) = delete;
};

访问结构体成员

访问结构的成员,使用成员访问运算符(​​.​​)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。

实例2:

/*******************************************************************
* > File Name: struct.cpp
* > Create Time: 2021年09月 2日 11:10:36
******************************************************************/
#include <iostream>
#include <cstring>
using namespace std;

struct Books{
char name[30];
char author[20];
char subject[100];
int bookId;
};

int main(void)
{
struct Books book1; /* 创建一个结构体对象 */
struct Books book2; /* 创建一个结构体对象 */

/* 实例化对象 */
strcpy(book1.name, "Linux驱动学习");
strcpy(book1.author, "张三");
strcpy(book1.subject, "学习驱动开发");
book1.bookId = 100;

/* 实例化对象 */
strcpy(book2.name, "C++精讲");
strcpy(book2.author, "李四");
strcpy(book2.subject, "学习C++开发");
book2.bookId = 1000;

cout << "书名:" << book1.name << endl;
cout << "作者:" << book1.author << endl;
cout << "主题:" << book1.subject << endl;
cout << "ID : " << book1.bookId << endl;

cout << "===========================" << endl;
cout << "书名:" << book2.name << endl;
cout << "作者:" << book2.author << endl;
cout << "主题:" << book2.subject << endl;
cout << "ID : " << book2.bookId << endl;

return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day4> make 
g++ -o struct struct.cpp -g -Wall
PS E:\fly-prj\cplusplus\day4> .\struct.exe
书名:Linux驱动学习
作者:张三
主题:学习驱动开发
ID : 100
===========================
书名:C++精讲
作者:李四
主题:学习C++开发
ID : 1000

结构作为函数参数

可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。

实例3:

/*******************************************************************
* > File Name: struct1.cpp
* > Create Time: 2021年09月 2日 11:32:13
******************************************************************/
#include <iostream>
#include <cstring>
using namespace std;

struct Books{
char name[30];
char author[20];
char subject[100];
int bookId;
};

void printBook(struct Books book);
int main(void)
{
struct Books book1;
struct Books book2;

strcpy(book1.name, "Linux驱动学习");
strcpy(book1.author, "张三");
strcpy(book1.subject, "学习驱动开发");
book1.bookId = 100;

strcpy(book2.name, "C++精讲");
strcpy(book2.author, "李四");
strcpy(book2.subject, "学习C++开发");
book2.bookId = 1000;

printBook(book1);
cout << "===========================" << endl;
printBook(book2);

return 0;
}

void printBook(struct Books book)
{
cout << "书名:" << book.name << endl;
cout << "作者:" << book.author << endl;
cout << "主题:" << book.subject << endl;
cout << "ID : " << book.bookId << endl;
}

编译、运行:

PS E:\fly-prj\cplusplus\day4> make 
g++ -o struct1 struct1.cpp -g -Wall
PS E:\fly-prj\cplusplus\day4> .\struct1.exe
书名:Linux驱动学习
作者:张三
主题:学习驱动开发
ID : 100
===========================
书名:C++精讲
作者:李四
主题:学习C++开发
ID : 1000

指向结构的指针

可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似。

实例4

/*******************************************************************
* > File Name: struct2.cpp
* > Create Time: 2021年09月 2日 11:45:05
******************************************************************/
#include <iostream>
#include <cstring>
using namespace std;

struct Books{
char name[30];
char author[20];
char subject[100];
int bookId;
};

void printBook(struct Books *book);
int main(void)
{
struct Books book1;
struct Books book2;

strcpy(book1.name, "Linux驱动学习");
strcpy(book1.author, "张三");
strcpy(book1.subject, "学习驱动开发");
book1.bookId = 100;

strcpy(book2.name, "C++精讲");
strcpy(book2.author, "李四");
strcpy(book2.subject, "学习C++开发");
book2.bookId = 1000;

printBook(&book1);
cout << "===========================" << endl;
printBook(&book2);

return 0;
}

void printBook(struct Books *book)
{
cout << "书名:" << book->name << endl;
cout << "作者:" << book->author << endl;
cout << "主题:" << book->subject << endl;
cout << "ID : " << book->bookId << endl;
}

编译、运行:

PS E:\fly-prj\cplusplus\day4> make
g++ -o struct2 struct2.cpp -g -Wall
PS E:\fly-prj\cplusplus\day4> .\struct2.exe
书名:Linux驱动学习
作者:张三
主题:学习驱动开发
ID : 100
===========================
书名:C++精讲
作者:李四
主题:学习C++开发
ID : 1000

实例5

struct MediaProperties
{
MediaProperties() :
m_AudioExtensions(""),
m_VideoExtensions(""),
m_ImageExtensions(""),
m_MediaPlaylistExtensions(""),
m_AudioSync(""),
m_AudioDevice(""),
m_VideoDevice(""),
m_VideoPosX(0),
m_VideoPosY(0),
m_DatabasesPath(TESTDATA_PATH),
m_ImagesPath(""),
m_SkipMetadata(false),
m_IgnoreScope(false),
m_MaxFiles{0},
m_MaxFolders{0},
m_MaxFilesPerFolder{0},
m_MaxFolderDepth{0},
m_MaxFilesPerPlaylist{0}
{}

MediaProperties(std::string strAudioExtensions,
std::string strVideoExtensions,
std::string strImageExtensions,
std::string strMediaPlaylistExtensions,
std::string strAudioSync,
std::string strAudioDevice,
std::string strVideoDevice,
int iVideoPosX,
int iVideoPosY,
std::string strDatabasePath,
std::string strImagesPath,
bool bSkipMetadata,
bool bIgnoreScope,
size_t iMaxFiles,
size_t iMaxFolders,
size_t iMaxFilesPerFolder,
size_t iMaxFolderDepth,
size_t iMaxFilesPerPlaylist) :
m_AudioExtensions(strAudioExtensions),
m_VideoExtensions(strVideoExtensions),
m_ImageExtensions(strImageExtensions),
m_MediaPlaylistExtensions(strMediaPlaylistExtensions),
m_AudioSync(strAudioSync),
m_AudioDevice(strAudioDevice),
m_VideoDevice(strVideoDevice),
m_VideoPosX(iVideoPosX),
m_VideoPosY(iVideoPosY),
m_DatabasesPath(strDatabasePath),
m_ImagesPath(strImagesPath),
m_SkipMetadata(bSkipMetadata),
m_IgnoreScope(bIgnoreScope),
m_MaxFiles{iMaxFiles},
m_MaxFolders{iMaxFolders},
m_MaxFilesPerFolder{iMaxFilesPerFolder},
m_MaxFolderDepth{iMaxFolderDepth},
m_MaxFilesPerPlaylist{iMaxFilesPerPlaylist}
{}

MediaProperties(const MediaProperties &) = default;
MediaProperties(MediaProperties &&) = default;
MediaProperties & operator=(const MediaProperties &) = default;
MediaProperties & operator=(MediaProperties &&) = default;
~MediaProperties() = default;

std::string m_AudioExtensions;
std::string m_VideoExtensions;
std::string m_ImageExtensions;
std::string m_MediaPlaylistExtensions;
std::string m_AudioSync;
std::string m_AudioDevice;
std::string m_VideoDevice;
int m_VideoPosX;
int m_VideoPosY;
std::string m_DatabasesPath;
std::string m_ImagesPath;
bool m_SkipMetadata;
bool m_IgnoreScope;
size_t m_MaxFiles;
size_t m_MaxFolders;
size_t m_MaxFilesPerFolder;
size_t m_MaxFolderDepth;
size_t m_MaxFilesPerPlaylist;
};

​typedef​​ 关键字

下面是一种更简单的定义结构的方式,您可以为创建的类型取一个"​​别名​​"。例如:

typedef struct Books{
char name[30];
char author[20];
char subject[100];
int bookId;
}BOOK;
BOOK book1, book2;