C++中struct和class的区别

本文探讨了C++中struct与class的区别,包括默认访问权限、继承方式、以及是否可以用大括号初始化等关键特性,并解释了struct如何在保持数据结构特性的同时,具备更多面向对象的功能。

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

一、

 C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。

    struct能包含成员函数吗?   能!

    struct能继承吗?          能!!

    struct能实现多态吗?       能!!!

 

     最本质的一个区别就是默认的访问控制,体现在两个方面:

    1)默认的继承访问权限。struct是public的,class是private的。

       写如下的代码:

    struct A

    {

      char a;

    };

    struct B : A

    {

      char b;

    };

    这个时候B是public继承A的。如果都将上面的struct改成class,那么B是private继承A的。这就是默认的继承访问权限。所以我们在平时写类继承的时候,通常会这样写:

    struct B : public A

    就是为了指明是public继承,而不是用默认的private继承。

    当然,到底默认是public继承还是private继承,取决于子类而不是基类。我的意思是,struct可以继承class,同样class也可以继承struct,那么默认的继承访问权限是看子类到底是用的struct还是class。如下:

    struct A{};

    class B : A{};    //private继承

    struct C : B{};  //public继承

 

    2)struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。

    3)“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。

 

    4) 还是上面所说的,C++中的struct是对C中的struct的扩充,既然是扩充,那么它就要兼容过去C中struct应有的所有特性。例如你可以这样写:

    struct A    //定义一个struct

    {

     char c1;

     int  n2;

     double db3;

    };

    A a={'p',7,3.1415926};  //定义时直接赋值

    也就是说struct可以在定义的时候用{}赋初值。

    向上面的struct中加入一个构造函数(或虚函数),struct也不能用{}赋初值了。的确,以{}的方式来赋初值,只是用一个初始化列表来对数据进行按顺序的初始化,如上面如果写成A a={'p',7};则c1,n2被初始化,而db3没有。这样简单的copy操作,只能发生在简单的数据结构上,而不应该放在对象上。加入一个构造函数或是一个虚函数会使struct更体现出一种对象的特性,而使此{}操作不再有效。事实上,是因为加入这样的函数,使得类的内部结构发生了变化。而加入一个普通的成员函数呢?你会发现{}依旧可用。其实你可以将普通的函数理解成对数据结构的一种算法,这并不打破它数据结构的特性。至于虚函数和普通成员函数有什么区别,我会具体写篇文章讨论。

    那么,看到这里,我们发现即使是struct想用{}来赋初值,它也必须满足很多的约束条件,这些条件实际上就是让struct更体现出一种数据机构而不是类的特性。那为什么我们在上面仅仅将struct改成class,{}就不能用了呢?其实问题恰巧是我们之前所讲的——访问控制!你看看,我们忘记了什么?对,将struct改成class的时候,访问控制由public变为private了,那当然就不能用{}来赋初值了。加上一个public,你会发现,class也是能用{}的,和struct毫无区别!!!

  从上面的区别,我们可以看出,struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。

 

二、

关于使用大括号初始化
  class和struct如果定义了构造函数的话,都不能用大括号进行初始化
  如果没有定义构造函数,struct可以用大括号初始化。
  如果没有定义构造函数,且所有成员变量全是public的话,可以用大括号初始化。
关于默认访问权限
  class中默认的成员访问权限是private的,而struct中则是public的。
关于继承方式
  class继承默认是private继承,而struct继承默认是public继承。
  且看如下代码(看看编译器给出的错误信息):

class T1
{
 public:
  void f()
  {
   cout<<"T1::f()"<<endl;
  }
 int x,y;
};
struct T2
{
 int x;
 void f(){cout<<"T2::f()"<<endl;}
};
struct TT1 : T1
{
};
class TT2 : T2
{
};
int main()
{
 TT1 t1;
 TT2 t2;
 t1.f();
 t2.f();
}

关于模版
  在模版中,类型参数前面可以使用class或typename,如果使用struct,则含义不同,struct后面跟的是“non-type template parameter”,而class或typename后面跟的是类型参数。

template <struct X>
void f(X x)
{
}
//出错信息:d:codecpptestcpptestcpptest.cpp(33) : error C2065: 'X' : undeclared identifier

<think>嗯,用户问的是C++structclass区别,这确实是一个基础但重要的问题。我需要先回忆一下两者的主要区别,然后组织答案。首先,默认的访问权限应该是关键点,struct默认是public,而class默认是private。接着,继承时的默认访问权限,struct是public继承,class是private。不过用户可能已经知道这些,可能需要更深入的内容。然后想到模板参数中,可以用struct来声明参数,而class不行?或者反过来?可能记混了,需要查证。比如,模板定义时,template<typename T>template<classT>是等效的,但如果是模板模板参数,可能需要用class关键字,struct不行。这点可能需要确认,但用户可能对此不太关心,属于较高级的内容。 另外,C++struct可以像class一样有成员函数、构造函数、继承等,这点C不同。用户可能从C转来,所以需要强调C++struct的增强功能。同时,习惯用法上,struct常用于数据聚合,而class用于更复杂的对象,但这不是语法上的区别,而是约定俗成的。还要注意是否存在其他细微差别,比如关键字在定义模板时的使用,或者友元的处理?可能没有。另外,是否有关于前向声明的区别?例如,前向声明structclass时是否会影响默认的访问权限?例如,声明classA;structA;是否会影响其成员的默认访问权限?应该会,因为前向声明使用struct的话,后续定义时默认访问是public,而class则是private。需要确保引用中的内容是否正确。例如,引用[4]提到更多差异,可能需要参考。例如,关于成员枚举的作用域,structC++中会创建作用域,而C中不会,这点在C++structclass是否一致?应该是一致的,因为C++structclass的主要区别在于默认访问权限继承,其他特性基本相同。 用户可能还关心使用场景,什么时候用struct,什么时候用class。这涉及编程风格,通常struct用于简单数据容器,而class用于封装复杂行为。但需要指出这只是习惯而非强制。另外,是否有C++11/14/17后的新特性影响两者区别?比如聚合初始化,struct如果所有成员都是public,可能更适用聚合初始化,而class如果有private成员则不行。但这也取决于具体的构造函数成员访问权限的设置,不完全是structclass区别,而是访问权限导致的。 需要确保回答准确,避免错误。例如,模板参数中的使用,可能用户会混淆,但实际在模板声明时,typenameclass可以互换,但struct不能用于模板参数声明。例如,template<struct T>是错误的,必须用class或typename。这点需要确认,但可能属于进阶内容,用户可能不需要,但可以提及。 总结,回答的结构应该分点,清晰列出主要区别:默认访问权限、继承时的默认权限、使用习惯,可能还有模板中的使用差异。然后给出使用建议,并附上相关问题。同时,引用中的内容需要正确对应,比如引用[4]提到更多差异,但可能已经涵盖在回答中。需要检查是否有遗漏点,比如友元声明是否有区别?应该没有,structclass在友元声明上是一样的。另外,关于类型名称,前向声明时使用structclass是否会影响类型在代码中的使用?比如,前向声明为struct A后,定义时必须用structA{},还是可以用classA{}?实际上,structclass在定义时是互斥的,前向声明为struct的类型必须用struct定义,否则编译错误。例如:struct A; classA {}; //错误,重复定义或者:classA;struct A{};//错误所以,前向声明必须定义一致,但这是否属于structclass区别呢?可能属于语法要求,但不算两者的差异,而是声明一致性的问题。可能用户不太关心这点,所以可以忽略。 最后,示例代码可能有助于说明,比如定义一个struct一个class,展示默认访问权限的不同。例如:struct MyStruct {intx;//默认public};class MyClass {intx;//默认private};这样用户可以直观看到区别。同时,继承的例子: structDerivedStruct: Base{};//默认public继承class DerivedClass :Base {}; //默认private继承这样对比更明确。 确保回答符合用户的需求,可能用户是初学者,需要明确且简洁的对比,避免过于深入高级话题。同时,相关问题可以涉及使用场景、性能差异(实际上没有)、或者历史原因等。</think>在 C++ 中,`struct` `class` 的核心差异主要体现在默认访问权限继承行为上,以下是具体对比: --- ### **1. 默认访问权限** - **`struct`**:成员继承关系**默认是 `public`** 例如: ```cpp struct MyStruct { int value; // 默认为 public }; ``` - **`class`**:成员继承关系**默认是 `private`** 例如: ```cpp class MyClass { int value; // 默认为 private }; ``` --- ### **2. 默认继承权限** - **`struct` 继承**:默认是 `public` 继承 ```cpp struct DerivedStruct : Base {}; // 等价于 public Base ``` - **`class` 继承**:默认是 `private` 继承 ```cpp class DerivedClass : Base {}; // 等价于 private Base ``` --- ### **3. 使用习惯** - **`struct`**:常用于**数据聚合**(如 POD 类型[^1]),或需要公开所有成员的场景。 例如:坐标点、配置参数等。 ```cpp struct Point { int x, y; void print() { std::cout << x << ", " << y; } }; ``` - **`class`**:用于**封装复杂行为**,强调数据隐藏接口设计。 例如:文件读写器、网络连接等。 ```cpp class FileReader { private: std::string path; public: explicit FileReader(const std::string& p) : path(p) {} std::string read(); }; ``` --- ### **4. 模板参数声明** - 声明模板参数时,`class` `typename` 可互换,但 `struct` **不可用**: ```cpp template <class T> // 合法 template <typename T> // 合法 template <struct T> // 非法! ``` --- ### **5. 前向声明差异** - 前向声明 `struct` 或 `class` 会影响后续定义的默认权限: ```cpp struct A; // 后续定义时必须用 struct,且成员默认 public class B; // 后续定义时必须用 class,且成员默认 private ``` --- ### **总结** - **语法差异**:仅默认访问权限继承行为不同,其他特性(如成员函数、继承、多态)完全一致[^4]。 - **设计意图**:`struct` 强调数据透明性,`class` 强调封装性[^3]。 - **编程规范**:Google C++ 风格指南建议,仅当仅有数据成员时用 `struct`,否则用 `class`[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值