代码之家  ›  专栏  ›  技术社区  ›  palm3D

C++中结构与类的区别是什么?

  •  405
  • palm3D  · 技术社区  · 17 年前

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

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

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

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

    我确信在C++规范中晦涩难懂的地方还有其他不同之处。

    29 回复  |  直到 17 年前
        1
  •  444
  •   Cheers and hth. - Alf    10 年前

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

    Quthe标准(在C 98+11+C++中的第11 2.2):

    在没有 访问说明符 对于基类,假定为public 当声明派生类时 结构 在声明类时假定为private .

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

    用定义的类的成员 关键字 私有的 通过 违约。定义的类的成员 用关键字 结构 联盟 公众的 默认情况下。

    附加区别:关键字 class 可用于声明模板参数,而 struct 关键字不能这样使用。

        2
  •  155
  •   Assaf Lavie    12 年前

    引用 The C++ FAQ ,

    [7.8]两者的区别是什么? 关键字结构和类?

    a的成员和基类 结构在默认情况下是公共的,而在 类,它们默认为private。注: 你应该做你的基础课程 明确公开、私人或 受保护,而不是依赖 默认值。

    否则,结构和类 功能等效。

    好吧,够干净了 技术讲座。情感上,大多数 开发人员有很强的区别 在类和结构之间。一 结构只是感觉像一个开放的堆 一点一点的 封装或功能。一 课堂感觉像是一种生活 社会责任成员 智能服务,强大 封装屏障,以及一口井 定义的接口。因为那是 大多数人已经拥有的内涵, 您可能应该使用结构 关键字,如果您的类 很少有方法和公共数据 (这样的事情确实存在于精心设计的 系统!),否则你应该 可能使用class关键字。

        3
  •  109
  •   Jon Hanna    10 年前

    记住C++的起源和与C.的兼容性是值得记住的。

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

    在使用面向对象的方法时,默认为公共的通常被认为是坏主意,所以在制作一种C形式的C,它本身就有利于OOP(您可以在C中做OO,但它对您没有帮助)这是C++中的想法(最初是“C类”),默认情况下让成员私有是有意义的。

    另一方面,如果stroustrup改变了 struct 因此,默认情况下它的成员是私有的,它将破坏兼容性(它不再像标准散布的那样是真的,但是所有有效的C程序也是有效的C++程序,这对给予C++的立足点有很大的影响)。

    一个新的关键词, class 被引入时与结构完全相同,但默认情况下是私有的。

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

    一般来说,人们在做结构在C中的使用方式;公共成员,没有构造函数(只要它不在联合中,那么 可以 在结构中有构造器,就像在类中一样,但人们往往不这样做)、没有虚拟方法等。因为语言与阅读代码的人交流的程度和指导机器的程度一样高(否则我们会坚持使用汇编和原始VM操作码),所以最好还是坚持这样做。

        4
  •  31
  •   Community Mohan Dere    9 年前

    类的成员在默认情况下是私有的。默认情况下,结构的成员是公共的。除此之外,没有其他区别。另请参见 this question .

        5
  •  27
  •   crashmstr    17 年前

    根据stroustrup在 C++ Programming Language :

    你使用哪种风格取决于环境和品味。我通常喜欢用 struct 对于具有所有公共数据的类。我认为这些类“不是很合适的类型,只是数据结构”。

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

        6
  •  9
  •   64BitBob    17 年前

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

    类是一种不同类型的抽象数据类型,它试图确保信息隐藏。在内部,可以有各种加工、方法、温度变量、状态变量。所有这些都用于向希望使用类的任何代码提供一致的API。

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

    但是,您需要了解这些仅仅是抽象。创建看起来很像类的结构和看起来很像结构的类是完全可能的。事实上,最早的C++编译器仅仅是将C++代码转换成C的预编译器,因此这些抽象对逻辑思维是有益的,不一定是计算机本身的财富。

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

        7
  •  9
  •   Suraj K Thomas    10 年前

    1)类成员默认为私有,结构成员默认为公共。

    例如,程序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)从类/结构派生结构时,基类/结构的默认访问说明符为public。并且在派生类时,默认访问说明符是私有的。

    例如,程序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;
    }
    
        8
  •  8
  •   Tim Cooper    14 年前

    唯一的区别是类和结构的默认继承,毫无疑问,它们分别是私有的和公共的。

        9
  •  4
  •   MSalters    17 年前

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

        10
  •  4
  •   KPexEA    17 年前

    还有一点需要注意,如果您更新了一个旧版应用程序,该应用程序具有使用类的结构,则可能会遇到以下问题:

    旧代码有结构,代码被清除,并改为类。 然后将一两个虚拟函数添加到新的更新类中。

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

    如果在旧代码中某个地方使用memfill将结构全部清除为零,这将如何破坏旧的遗留代码,这也将增加额外的指针数据。

        11
  •  4
  •   melpomene    8 年前
    1. 默认情况下,结构的成员是公共的,类的成员是私有的。
    2. 来自其他结构或类的结构的默认继承是公共的。来自其他结构或类的类的默认继承是私有的。
    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。

        12
  •  3
  •   Stefan Popescu    14 年前

    另一个主要区别是在模板方面。据我所知,在定义模板而不是结构时,可以使用类。

    template<class T> // OK
    template<struct T> // ERROR, struct not allowed here
    
        13
  •  2
  •   nutario    17 年前

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

    因此,再一次:在C++中,一个结构与一个类是相同的,除了一个结构的成员在默认情况下具有公共可见性,但是一个类的成员在默认情况下具有私有可见性。

        14
  •  2
  •   finnw    17 年前

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

        15
  •  2
  •   Gregory Pakosz    16 年前

    ISO IEC 14882-2003标准

    9课

    第3章

    结构是用定义的类 这个 类密钥 struct 其成员 基本类(第10条)是 公共违约(第11条)。

        16
  •  2
  •   Bathsheba    7 年前
    1. 用关键字定义的类的成员 class private 默认情况下。用关键字定义的类的成员 struct (或) union public 默认情况下。

    2. 如果没有基类的访问说明符, 公众的 假设当 衍生的 类已声明 结构 私有的 在声明类时假定 .

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

    4. 你可以使用 template<class T> 但不是 template<struct T> .

    还要注意,C++标准允许您将类型声明为 结构 然后使用 声明类型时,反之亦然。也, std::is_class<Y>::value true 因为Y是一个 结构 和A 但是 false 对于一个 枚举类 .

        17
  •  1
  •   ymett    15 年前

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

    值得注意的是(特别是因为ASKER很可能使用MSVC++),因为他提到了“非托管”C++,即VisualC++在某些情况下抱怨如果一个类被声明为 class 然后定义为 struct (或者可能相反),尽管标准规定这是完全合法的。

        18
  •  1
  •   yshivakathik    14 年前
    • . 在类中,默认情况下所有成员都是私有的,但在结构中 默认情况下,成员是公共的。

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

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

      类的默认访问类型是private,并且 继承是私有的。类应用于分组数据和 对该数据进行操作的方法。

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

      C++中的结构和类是按值传递的,除非显式 去引用。在其他语言中,类和结构可能 不同的语义-即对象(类的实例)可以被传递 通过引用和结构可以通过值传递。注:有 与此问题关联的注释。请参阅讨论页 添加到对话中。

        19
  •  1
  •   UKMonkey    9 年前

    虽然其他答案暗示了这一点,但并没有明确提及——结构是C兼容的,这取决于用法;类是不兼容的。

    这意味着,如果要编写一个要与C兼容的头,那么除了struct(在C世界中,struct不能有函数,但可以有函数指针)之外,没有其他选项。

        20
  •  -1
  •   snow    11 年前

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

    当用大量没有类的人开发大型项目时,最终可能会得到复杂的耦合代码,因为每个人都使用他们想要的任何函数和数据。类提供了权限控件和固有项,以增强分离和重用代码。

    如果你阅读了一些软件工程原理,你会发现没有类,大多数标准都不容易实现。例如: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

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

        21
  •  -1
  •   kiriloff    11 年前

    您可以考虑将此作为何时使用结构或类的指导, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

    _如果 类型很小,通常寿命短,或者通常嵌入 其他对象。

    x避免定义结构,除非类型具有 以下特点:

    它逻辑上表示一个值, 类似于原始类型(int、double等)。

    它有一个实例 大小小于16字节。

    它是不变的。

    它不必装箱 经常。

        22
  •  -2
  •   MOBITI MAHENGE    13 年前

    两者之间的区别 结构 C++中的关键字是,当特定的复合数据类型没有特定的说明符,那么默认情况下 结构 联盟 是只考虑数据隐藏的公共关键字,而类是考虑程序代码或数据隐藏的私有关键字。总是有些程序员使用 结构 用于数据和 为了代码的缘故。有关更多信息,请联系其他来源。

        23
  •  -2
  •   Wageesha    13 年前

    在所有这些因素中,可以得出这样的结论:概念类非常适合于表示现实世界的对象,而不是“结构”。这主要是因为类中使用的OOP概念在解释现实世界场景时非常实用,因此更容易将它们合并到现实中。例如,对于结构,默认继承是公共的,但如果我们对现实世界来说,这是荒谬的。但是在一个类中,默认继承是私有的,这更现实。

    总之,我需要证明的是,类是一个更广泛的、现实世界中适用的概念,而结构是一个原始的概念,内部组织很差(尽管结构遵循OOP概念,但它们的含义很差)。

        24
  •  -3
  •   Tushar Bobade    12 年前

    OOPS中structure和class关键字的主要区别在于,在结构中不存在public和private成员声明,数据成员和成员函数可以定义为public、private和protected。

        25
  •  -3
  •   Yug Rawal    9 年前

    结构和类的主要区别在于,在结构中,只能声明不同数据类型的数据变量,而在类中,可以声明数据变量、成员函数,从而可以通过函数操作数据变量。

    ->我在类vs结构中发现的另一个便利之处是,在程序中实现文件时,如果您想对一个结构的每一组新操作进行一次又一次的操作,则需要生成一个单独的函数,并且需要在从文件中读取结构的对象后传递它,以便对其进行一些操作。 而在类中,如果您使一个函数每次对所需的数据执行某些操作,则很容易,只需从文件中读取对象并调用该函数即可。

    但这取决于程序员认为合适的方式……根据我的说法,每次我都喜欢类,因为它支持OOPS,这就是它几乎在所有语言中实现的原因,以及它在所有时间编程中的出色功能;-)

    是的,我忘记提到的最不可原谅的区别是,类支持数据隐藏,也支持在结构不支持的情况下对内置数据类型执行的操作!

        26
  •  -4
  •   Ali    15 年前

    我发现了另一个不同。如果不在类中定义构造函数,编译器将定义一个。但在结构中,如果不定义构造函数,编译器也不会定义构造函数。因此,在某些情况下,我们确实不需要构造函数,结构是更好的选择(性能提示)。 为我糟糕的英语感到抱歉。

        27
  •  -4
  •   Frank Myat Thu    12 年前

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

    例如:

    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.
    }
    

    在主要方法中,
    我可以使用为这个类分配内存的新操作符创建这个类的实例
    并将其基地址存储到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. MyCaseObjuts1
    2. MyCaseObjuts2

    并将指向相同的内存位置。
    它基本上将相同的内存位置分配给相同类型的另一个变量。

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

    “MyClassObject1.dataMember=10;”在这一行,对象的数据成员都将包含10的值。
    “MyClassObject2.dataMember=20;”在这一行,对象的数据成员都将包含值20。
    最终, 我们正在通过指针访问对象的数据成员。

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

    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和
    使用“_mystructtobject1.data member=10”将值10分配给结构的数据成员。

    在下一行,
    我声明另一个类型为mystructure的变量mystructobject2,并将mystructobject1分配给它。
    在这里,.NET C编译器创建另一个mystructureObject1对象的副本,并
    将内存位置分配给mystructure变量mystructtobject2。

    因此,无论我们对mystructTobject1做什么更改,都不会对mystructTrue类型的另一个变量mystructTobject2产生影响。
    这就是为什么我们说结构是价值类型。

    因此,类的直接基类是对象,结构的直接基类是从对象继承的ValueType。
    类将支持继承,而结构将支持。

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

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

        28
  •  -4
  •   Eric Hill    7 年前

    **更新:**请忽略此回复。我没有考虑结构的值未初始化但恰好是0的可能性。结构和类之间没有初始化差异。


    我看到结构和类之间的另一个不同之处在于默认初始化。

    struct Foo {
        int a;
    };
    
    class Bar {
        int a;
    };
    
    class Tester {
        Foo m_Foo = Foo();
        Bar m_Bar = Bar();
    
    public:
        Tester() {}
    };
    
    int main() {
        auto myTester = Tester();
    }
    

    运行该代码并检查MyTester。您会发现,对于m诳foo,结构m诳foo.a已初始化为0,但对于m诳bar,类m诳bar.a未初始化。因此,对于结构和类,默认的构造函数所做的似乎确实有所不同。我在Visual Studio中看到了这一点。

        29
  •  -8
  •   Naveen    11 年前

    结构和阶级有三个基本区别

    第1个内存是为堆栈内存中的结构(接近编程语言)保留的,堆栈内存中的类是否只为reffrence保留,实际内存在堆栈内存中保留。

    第二个-默认情况下,无论类是否视为私有,结构都视为公共。

    第三,不能在结构中重复使用代码,但在类中,我们可以多次重复使用相同的代码,称为inhertence