C++中结构体(struct)
我们知道C++中的 struct 对C中的 struct 进行了扩充,它不再是只能用来封装不同类型数据的数据结构了,而是拥有了更多的功能,例如:可以包含成员函数,可以继承,可以实现多态!!,这些功能与C++中的类很相似。
那么接下来我们解剖一下C++中结构体struct与类class的区别。
C++中struct与class的区别
一、class和struct 本身成员的默认访问级别不同
这是最本质的区别,结构体的成员和成员函数在默认情况下的访问级别是公有的(public),类的成员和成员函数在默认情况下的访问级别是私有的(private)。
注意: 二者的访问方式都是 对象名+点(对象成员选择运算符)+访问对象成员
不用多介绍,我们直接通过下面的代码进行区分和理解:
- struct的用法:不加任何访问限定符,struct默认访问权限是public,即成员可直接在结构体外被访用。其他用法与class类似,即对象定义时struct类型也可省略。
#include <iostream>
using namespace std;
struct Student{
public:
int Age ;
char Name[16];
};
struct Student1{
int Age =22 ;
char Name[16] = "李四";
};
int main()
{
struct Student stu = { 18,"张三" }; //struct初始化
cout<< stu.Name <<" " <<stu.Age<< endl;
struct Student1 s ;
cout<< s.Name <<" " <<s.Age<<endl;
s.Age = 55;
cout<< "修改李四年龄后:" << s.Name <<" " <<s.Age;
return 0;
}
- class的用法:不加任何访问限定符时,class默认访问权限是private,即类中的成员不能直接在类外被访问。若想实现在类外被访问则必须加public
#include <iostream>
using namespace std;
class Student{
int Age;
string Name;
};
class Student1{
public:
int Age =22;
string Name ="李四";
};
int main()
{
Student stu = {18,"张三"}; //class初始化
cout << stu.Name <<" "<< stu.Age <<endl;
Student1 s;
cout << s.Name <<" "<< s.Age <<endl;
s.Age = 55;
cout<< "修改李四年龄后:" << s.Name <<" " <<s.Age;
return 0;
}
修复 :在代码第4行和第5行中间加上public:
,可修复报错处,得到正确结果。
二、class和struct 继承类的默认访问级别不同
简单来说就是,
结构体常见的继承方式 struct A{ char a;}; struct B:A{char b;};
,这里结构体B是A的公有继承,即基类中所有public成员在派生类中为public属性;结构体外的函数调用时可使用B.a 进行访问。
但如果将上面一句代码中struct改成class,那么类B就是A的私有继承,即基类中的所有public成员在派生类中均为private属性;类外的函数调用时无法通过B.a进行访问。这就是class与struct在继承中默认访问权限的区别,如果在类中想将类B写成A的公有继承,需要改写为 class B:public A
。
通过下面的代码可以帮助更好的理解:
#include <iostream>
using namespace std;
class Student
{
public:
int Age = 18;
};
class A: Student{ //非"class A: public Student"即表示私有继承
public:
int GetAge() { return Age;} //派生类可以访问基类的public成员
};
int main()
{
class Student s;
class A a;
cout <#include <iostream>
using namespace std;
struct PersonA{
int Sex = 0;
};
struct PersonB:PersonA{
int GetSex() { return Sex;} //该派生类预期可以访问基类的public成员
};
class StudentA
{
public:
int Age = 18;
};
class StudentB: public StudentA{
public:
int GetAge() { return Age;}
}; //classB 有public修饰
class StudentC: StudentA{
public:
int GetAge() { return Age;}
}; //classC 无public修饰
int main()
{
struct PersonB pb;
class StudentB sb;
class StudentC sc;
cout << "struct派生类访问基类的值:" << pb.Sex;
pb.Sex =1;
cout << " struct修改基类后的值:"<<pb.GetSex ()<<endl;
cout << "class派生类访问基类的值:" << sb.Age;
sb.Age =22;
cout << " class修改基类后的值:"<<sb.GetAge ()<<endl;
cout << "class派生类访问基类的值:" << sc.Age<<endl;
return 0;
}
修复 :把代码第23行改成class StudentC:public StudentA:
,可修复报错处,得到正确结果。
从上面的代码来看,二者说到底也只是默认访问权限的区别。且继承方式的默认访问权限与基类无关,而是由继承中的子类决定的。
也就是说struct可以继承class,同样class也可以继承struct,我们默认的继承访问权限要看子类到底是struct还是class。下面这段代码简单举例:
struct A {};class B{}; //private 继承
class A {};struct B{}; //public 继承
虽然这里struct 与class 的用法差不多,但是struct 仍然是一种数据结构的实现体,而class 则是一个对象的实现体。所以习惯struct 体内的变量叫做数据,class 内的变量叫做成员。
这里我想说明一点,即使struct 与class 可以依靠默认的访问权限进行区分,但是我们仍然应该养成在自己的程序里写明的习惯,方便别人的阅读。
三、赋值方式区别
给一个结构赋值:
struct A{char c1; int n2; float db3;};A a = {'a',1,3.14};
这样可以直接给结构体赋值,没有任何错误。但是要是将struct换成class就不行了。为什么呢?
其实就是因为class中有默认的构造函数、析构函数等。可以试着在上面结构中添加一个构造函数,会发现,上面的赋值语句失败了!所以真理很明确了!
我们平时使用{}来对结构赋值,是一个初始化列表形式进行初始化,这样简单的初始化只能用在简单的数据结构上,如果加上构造函数,那么struct会表现出一种对象的特性,因此再使用这种方式赋值就会失效!
也就是说当我们在一个结构中加入构造函数后,结构体的内部结构会发生变化;但加入一个普通函数,结构体内部结构依旧不变;因此可以理解为普通函数是一种对数据结构的算法,并不会打破原本数据的特性!
四、总结
之前自己总结的不够全面,正好看到他人的博客拿来借鉴一下。
以上总结内容参考博客 C++中结构体与类的区别介绍,可通过链接跳转查看。
有更多内容我会继续补充,记得关注博主哦~
如果你有更多想法也可以留言一起讨论,欢迎加入。