C ++中struct和class之间有什么区别?

时间:2008-09-18 14:09:59

标签: c++ oop class struct c++-faq

这个问题是already asked in the context of C#/.Net

现在我想学习C ++中结构和类之间的区别。请讨论技术差异以及在OO设计中选择其中一个的原因。

我将从一个明显的区别开始:

  • 如果您未指定public:private:,则结构的成员默认为公共;默认情况下,类的成员是私有的。

我确信在C ++规范的模糊角落中还有其他差异。

29 个答案:

答案 0 :(得分:449)

你忘记了类和结构之间棘手的第二个区别。

标准(C ++ 98到C ++ 11中的第11.2.2节):

  

缺少访问说明符   对于基类,假设是公共的   当声明派生类时   当声明类 class 时,假设 struct 和private。

为了完整起见,在(11.2)中定义了类和结构之间更广为人知的区别:

  

用。定义的类的成员   关键字私有   默认。定义了一个类的成员   使用关键字 struct union   默认为公开

其他差异:关键字class可用于声明模板参数,而struct关键字则无法使用。

答案 1 :(得分:157)

引用The C++ FAQ

  

[7.8]之间有什么区别   关键字struct和class?

     

a的成员和基类   struct默认是公共的,而在   class,他们默认为私有。注意:   你应该做你的基础课   明确的公共,私人或   保护,而不是依靠   默认值。

     

其他结构和类   在功能上等同。

     

好的,足够干净的吱吱声   技术谈话。情感上,大多数   开发人员有很大的区别   在类和结构之间。一个   结构只是感觉像一个开放的桩   比特很少   封装或功能。一个   上课感觉就像生活一样   负责任的社会成员   智能服务,强大   封装屏障,井   定义的界面。既然如此   大多数人已经拥有的内涵,   你应该使用结构   关键字,如果你有一个类   很少的方法和公共数据   (这样的事情确实存在于精心设计的中   系统!),但你应该   可能使用class关键字。

答案 2 :(得分:115)

值得记住C ++的起源,以及与C的兼容性。

C有结构,它没有封装的概念,所以一切都是公开的。

在采用面向对象的方法时,默认情况下公开通常被认为是一个坏主意,因此在制作一种本身有利于OOP的C形式时(你可以在C中做OO,但它不会帮助你)这是C ++中的想法(最初是“C With Classes”),默认情况下将成员设为私有是有意义的。

另一方面,如果Stroustrup改变了struct的语义,使其成员默认是私有的,那么它就会破坏兼容性(它不再像标准分歧那样经常出现,但都是有效的C程序也是有效的C ++程序,这对于给予C ++立足点有很大的影响。)

因此,引入了一个新的关键字class,它与结构完全相同,但默认情况下是私有的。

如果C ++是从头开始的,没有历史记录,那么它可能只有一个这样的关键字。它也可能不会产生影响。

一般来说,人们在做C语言中使用结构体时会倾向于使用struct;公共成员,没有构造函数(只要它不在联合中,你可以在结构中有构造函数,就像类一样,但人们往往不会),没有虚拟方法等等。语言与阅读代码的人进行交流,以指导机器(或者我们坚持使用汇编和原始VM操作码),坚持使用它是个好主意。

答案 3 :(得分:31)

Class'成员默认是私有的。 Struct的成员默认是公开的。除此之外,没有其他差异。另请参阅this question

答案 4 :(得分:28)

根据C++ Programming Language中的Stroustrup:

  

您使用哪种款式取决于环境和品味。我通常更喜欢将struct用于公开所有数据的类。我认为这类“不太合适,只是数据结构。”

从功能上讲,除了公共/私人

之外没有区别

答案 5 :(得分:9)

1)默认情况下,类的成员是私有的,struct的成员是公共的。

例如,程序1在编译时失败,程序2工作正常。

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2)从类/结构派生结构时,基类/结构的默认访问说明符是公共的。在派生类时,默认访问说明符是私有的。

例如,程序3在编译时失败,程序4工作正常。

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}

答案 6 :(得分:9)

STRUCT是一种抽象数据类型,它根据结构规范划分给定的内存块。结构在文件序列化/反序列化中特别有用,因为结构通常可以逐字写入文件。 (即获取指向结构的指针,使用SIZE宏计算要复制的字节数,然后将数据移入或移出结构。)

类是一种尝试确保信息隐藏的不同类型的抽象数据类型。在内部,可以有各种阴谋,方法,临时变量,状态变量。等等,它们都用于向希望使用该类的任何代码提供一致的API。

实际上,结构是关于数据的,类是关于代码的。

但是,您需要了解这些仅仅是抽象。完全可以创建看起来很像类和类看起来很像结构的结构。事实上,最早的C ++编译器只是将C ++代码转换为C的预编译器。因此,这些抽象是逻辑思维的一个好处,不一定是计算机本身的资产。

除了每种都是不同类型的抽象之外,Classes还为C代码命名难题提供了解决方案。由于您不能使用相同名称公开多个函数,因此开发人员习惯遵循_()模式。例如mathlibextreme_max()。通过将API分组到类中,类似的函数(这里我们称之为“方法”)可以组合在一起并保护其免受其他类中方法的命名。这允许程序员更好地组织他的代码并增加代码重用。从理论上讲,至少。

答案 7 :(得分:8)

唯一的另一个区别是类和结构的默认继承,不出所料,它们分别是私有的和公共的。

答案 8 :(得分:4)

  1. 默认情况下,结构的成员是公共的,默认情况下,类的成员是私有的。
  2. 来自另一个结构或类的Structure的默认继承是public。来自另一个结构或类的类的默认继承是私有的。
  3. class A{    
    public:    
        int i;      
    };
    
    class A2:A{    
    };
    
    struct A3:A{    
    };
    
    
    struct abc{    
        int i;
    };
    
    struct abc2:abc{    
    };
    
    class abc3:abc{
    };
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {    
        abc2 objabc;
        objabc.i = 10;
    
        A3 ob;
        ob.i = 10;
    
        //A2 obja; //privately inherited
        //obja.i = 10;
    
        //abc3 obss;
        //obss.i = 10;
    }
    

    这是在VS2005上。

答案 9 :(得分:4)

另外需要注意的是,如果您更新了使用类结构的旧应用程序,则可能会遇到以下问题:

旧代码具有结构,代码已清理,并且这些代码已更改为类。 然后将一个或两个虚函数添加到新更新的类中。

当虚函数在类中时,编译器会在内部添加指向类数据的额外指针以指向函数。

如果在旧代码中某个地方使用memfill将结构清除为零来清除旧代码,这会破坏额外的指针数据。

答案 10 :(得分:4)

不在规范中,没有。主要区别在于程序员在2年内阅读您的代码时的期望。结构通常被认为是POD。当您为定义对象以外的目的定义类型时,结构也用于模板元编程。

答案 11 :(得分:3)

另一个主要区别在于模板。据我所知,您可以在定义模板时使用类,但不能使用结构。

template<class T> // OK
template<struct T> // ERROR, struct not allowed here

答案 12 :(得分:2)

  

ISO IEC 14882-2003

     

9个课程

     

§3

     

结构是一个定义的类    class-key struct;其成员   和基类(第10条)是   默认公开(第11条)。

答案 13 :(得分:2)

这只是一个惯例。可以创建结构来保存简单数据,但随后通过添加成员函数和构造函数来演化时间。另一方面,看到除了public之外的任何东西是不寻常的:在结构中访问。

答案 14 :(得分:2)

  1. 由关键字class定义的类的成员默认为private。默认情况下,用关键字struct(或union)定义的类的成员为public

  2. 在没有针对基类的访问说明的情况下,当派生的类被声明为publicstruct被假定为private时在声明类class时采用。

  3. 您可以声明enum class,但不能声明enum struct

  4. 您可以使用template<class T>,但不能使用template<struct T>

还要注意,C ++标准允许您将类型向前声明为struct,然后在声明类型时使用class,反之亦然。另外,对于Y为std::is_class<Y>::valuetruestructclass,对于falseenum class

答案 15 :(得分:2)

以下是一个很好的解释:http://carcino.gen.nz/tech/cpp/struct_vs_class.php

  

所以,还有一次:在C ++中,结构与类相同,只是结构的成员默认具有公共可见性,但是默认情况下类的成员具有私有可见性。

答案 16 :(得分:1)

classstruct之间的区别在于关键字之间的区别,而不是数据类型之间的区别。这两个

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

都定义一个类类型。在这种情况下,关键字的区别在于默认访问权限不同:

  • foo::x是公开的,而foo_base是公开继承的
  • bar::x是私有的,bar_base是私有继承的

答案 17 :(得分:1)

虽然其他答案暗示,但未明确提及 - 结构与C兼容,具体取决于使用情况;课不是。

这意味着如果你正在编写一个你希望与C兼容的标题,那么除了struct之外别无选择(在C世界中它不能有函数;但是可以有函数指针)。

答案 18 :(得分:1)

  • 。在类中,默认情况下所有成员都是私有的但是在结构中 会员在默认情况下是公开的。

    1. 对于结构体,没有类似构造函数和析构函数的术语,但是如果不提供,则类编译器会创建默认值。

    2. 当空类的Sizeof为1时,空结构的大小为0字节结构默认访问类型为public。结构应该 通常用于分组数据。

    3. 类默认访问类型是私有的,默认模式是 继承是私有的。应该使用一个类来分组数据和 对该数据进行操作的方法。

      简而言之,惯例是在目的时使用struct 分组数据,并在需要数据抽象时使用类, 也许继承。

      在C ++中,结构和类是按值传递的,除非明确说明 解除引用。在其他语言中,类和结构可能有 不同的语义 - 即。可以传递对象(类的实例) 通过引用和结构可以通过值传递。注意:有 与此问题相关的评论。请参阅讨论页面 加入对话。

答案 19 :(得分:1)

其他答案提到了私有/公共默认值,(但请注意,struct是一个类是一个结构;它们不是两个不同的项,只是两种定义同一项的方法)。

可能有趣的是(特别是因为提问者可能会使用MSVC ++,因为他提到“非托管”C ++)是在某些情况下,如果一个类声明为class然后定义,那么Visual C ++会抱怨与struct(或可能相反),尽管标准认为这是完全合法的。

答案 20 :(得分:-1)

类仅在软件工程的上下文中有意义。在数据结构和算法的上下文中,类和结构没有那么不同。没有任何规则限制该类的成员必须被引用。

在开发没有课程的大量项目的大型项目时,您可能最终得到复杂的耦合代码,因为每个人都使用他们想要的任何功能和数据。 class提供权限控制和内容来增强解耦和重用代码。

如果您阅读了一些软件工程原理,您会发现大多数标准在没有课程的情况下无法轻松实现。例如: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

顺便说一句,当一个struct分配一个内存碎片并包含几个变量时,值类型变量表示值被嵌入在分配struct的位置。相反,引用类型变量的值是外部的,并且由指针引用,该指针也嵌入在分配struct的位置。

答案 21 :(得分:-1)

您可以考虑这一点,了解何时选择结构或类https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx

  

√考虑到如果实例,则定义结构而不是类   类型很小,通常是短暂的或通常嵌入   其他对象。

     

X AVOID定义结构,除非类型具有全部结构   具有以下特点:

     

逻辑上代表单个值,   类似于原始类型(int,double等)。

     

它有一个实例   大小不超过16个字节。

     

这是不可改变的。

     

不必装箱   频繁。

答案 22 :(得分:-2)

在所有这些因素中,可以得出结论,概念类非常适合表示现实世界的对象而不是“结构”。很大程度上因为类中使用的OOP概念在解释现实世界场景时非常实用,因此更容易合并它们例如,默认继承对于结构是公共的,但是如果我们将这个规则应用于现实世界,那就太荒谬了。但是在类中,默认继承是私有的,这更加真实。

无论如何,我需要证明的是,Class是一个更广泛的,现实世界适用的概念,而Structure是一个原始的概念,内部组织很差(Eventhough struct遵循OOP概念,它们的含义很差)

答案 23 :(得分:-2)

C ++中 struct class 关键字之间的区别在于,当特定复合数据类型没有特定说明符时,默认情况下 struct union 是仅考虑数据隐藏的公共关键字,但class是考虑隐藏程序代码或数据的私有关键字。总有一些程序员使用 struct 表示数据, class 表示代码。有关更多信息,请联系其他来源。

答案 24 :(得分:-3)

oops中结构和类关键字的主要区别在于,结构中不存在公共和私有成员声明。数据成员和成员函数可以定义为public,private和protected。

答案 25 :(得分:-3)

struct和class之间的主要区别在于struct中只能声明不同数据类型的数据变量,而在类中,您可以声明数据变量,成员函数,因此可以通过函数操作数据变量。

- &GT;我在类vs struct中发现的另一个方便的事情是,如果你想在每个新的操作集上反复对结构进行一些操作,那么在程序中实现文件时,你需要创建一个单独的函数,你需要传递对象从文件中读取结构后对其进行一些操作。    在课堂上,如果你创建一个函数,每次都需要对数据进行一些操作..很容易你只需要从文件中读取对象并调用函数..

但是它依赖于程序员他/她认为合适的方式......根据我的说法我每次都喜欢上课,因为它支持OOP,这就是它几乎在所有语言中实现的原因以及它的有史以来的精彩特征编程; - )

是的,我忘记提到的最难忘的差异是,该类支持数据隐藏,还支持在内置数据类型中执行的操作,而struct不是!

答案 26 :(得分:-4)

类是引用类型,结构是值类型 当我说类是引用类型时,
基本上它们将包含实例变量的地址。

例如:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

在主要方法中,
我可以使用为该类分配内存的new运算符创建此类的实例 并将其基地址存储到MyClass类型变量(_myClassObject2)中。

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

在上面的节目中,     MyClass _myClassObject2 = _myClassObject1; 指令表示MyClass类型的两个变量

        
  1. myClassObject1
  2.     
  3. myClassObject2
  4. 并指向相同的内存位置 它基本上将相同的内存位置分配给另一个相同类型的变量。

    因此,如果我们在任何一个对象类型MyClass中所做的任何更改都会对另一个对象产生影响 因为两者都指向相同的内存位置。

    “_ myClassObject1.DataMember = 10;”在这一行,对象的数据成员都将包含值10.
    “_myClassObject2.DataMember = 20;”在这一行,对象的数据成员都将包含值为21的值 最后,我们通过指针访问对象的数据库。

    与类不同,结构是值类型。 例如:

    Structure MyStructure
    {
        Public Int DataMember;  //By default, accessibility of Structure data 
                                //members will be private. So I am making it as 
                                //Public which can be accessed out side of the structure.
    }
    
    Static Public void Main (string[] arg)
    {
        MyStructure _myStructObject1 = new MyStructure();
        _myStructObject1.DataMember = 10;
    
        MyStructure _myStructObject2 = _myStructObject1;
        _myStructObject2.DataMember = 20;
    }
    

    在上述计划中,
    使用new运算符和实例化MyStructure类型的对象 将地址存储到MyStructure类型的_myStructObject变量和
    使用“_myStructObject1.DataMember = 10”将值10分配给结构的数据成员。

    在下一行中,
    我声明另一个MyStructure类型的变量_myStructObject2并将_myStructObject1分配给它。
    这里.NET C#编译器创建了_myStructureObject1对象的另一个副本和
    将该内存位置分配到MyStructure变量_myStructObject2。

    因此,我们对_myStructObject1所做的任何更改都不会对MyStructrue类型的另一个变量_myStructObject2产生影响。
    这就是为什么我们说结构是价值类型。

    因此,类的直接Base类是Object,而Structure的直接Base类是继承自Object的ValueType 类将支持继承,而结构则不支持。

    我们怎么说?
    这背后的原因是什么?
    答案是Classes。

    它可以是抽象的,密封的,静态的和部分的,不能是私有的,受保护的和内部保护的。

答案 27 :(得分:-4)

我发现了另一个区别。如果您没有在类中定义构造函数,编译器将定义一个。但是在结构中如果没有定义构造函数,编译器也不会定义构造函数。所以在某些情况下我们真的不需要构造函数,struct是更好的选择(性能提示)。 抱歉我的英语不好。

答案 28 :(得分:-8)

结构和类之间有3个基本区别

1St-内存保留用于堆栈内存中的结构(接近编程语言),无论堆栈内存中的类是仅保留用于reffrence还是实际内存保留在堆内存中。

2Nd - 默认情况下,结构视为公共,是否将类视为私有。

3Rd-不能在结构中重用代码,但在课堂上我们可以在很多时间内重复使用相同的代码,称为inhertence