这个问题是 已经在 C#/.Net 的上下文中询问过.

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

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

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

我确信在 C++ 规范的不起眼的角落中还可以发现其他差异。

有帮助吗?

解决方案

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

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

在没有 访问说明符对于基类,在声明派生类时假设公众是公众的 结构体 并且在声明类时假定为 private 班级.

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

用关键字定义的类的成员 班级私人的 默认情况下。用关键字定义的类的成员 结构体 或者 联盟民众 默认情况下。

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

其他提示

引用 C++ 常见问题解答,

7.8]关键字结构和类之间有什么区别?

默认情况下,结构的成员和基础类是公共的,而在课堂上,它们默认为私有。笔记:您应该使基础类明确公开,私人或受保护,而不是依靠默认设置。

结构和类在功能上是等效的。

好的,足够的吱吱作响的干净技术谈话。在情感上,大多数开发人员在班级和结构之间做出了强烈的区别。一个结构只是感觉像是一堆开放的碎屑,几乎没有封装或功能。一个班级感觉就像是一个具有智能服务,强大的封装障碍和定义明确的界面的社会成员和负责任的成员。由于这是大多数人已经拥有的含义,因此,如果您的类具有很少的方法并且具有公共数据的类别(确实存在于设计良好的系统中!),则可能应该使用struct关键字,但是否则,您可能应该使用类关键词。

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

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

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

另一方面,如果 Stroustrup 改变了语义 struct 因此它的成员默认是私有的,它会破坏兼容性(随着标准的分歧,它不再那么常见,但所有有效的 C 程序也是有效的 C++ 程序,这对 C++ 的立足点产生了很大的影响)。

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

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

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

类的成员默认是私有的。默认情况下,Struct 的成员是公共的。除此之外没有其他区别。另请参阅 这个问题.

根据斯特鲁斯特鲁普在 C++ 编程语言:

您使用哪种风格取决于环境和品味。我通常更喜欢使用 struct 对于所有数据都是公开的类。我认为此类“不是完全正确的类型,只是数据结构”。

从功能上来说,除了公/私之外没有任何区别

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

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

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

但是,您确实需要了解这些只是抽象概念。完全有可能创建看起来很像类的结构以及看起来很像结构的类。事实上,最早的 C++ 编译器只是将 C++ 代码翻译为 C 的预编译器。因此,这些抽象有利于逻辑思维,但不一定是计算机本身的资产。

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

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。并且在派生类时,默认访问说明符是 private。

例如,程序 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;
}

唯一的其他区别是类和结构的默认继承,毫不奇怪,它们分别是私有的和公共的。

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

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

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

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

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

  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上的。

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
  1. 使用关键字定义的类的成员 classprivate 默认情况下。使用关键字定义的类的成员 struct (或者 union) 是 public 默认情况下。

  2. 如果基类没有访问说明符, public 假设当 衍生的 类已声明 structprivate 声明类时假定 class.

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

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

另请注意,C++ 标准允许您将类型前向声明为 struct, ,然后使用 class 声明类型时,反之亦然。还, std::is_class<Y>::valuetrue 因为 Y 是 struct 和一个 class, , 但是 falseenum class.

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

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

这只是一个约定。可以创建结构来保存简单数据,但稍后会通过添加成员函数和构造函数来演变。另一方面,除了公开之外,看到任何其他东西都是不寻常的:结构体中的访问。

ISO IEC 14882-2003

9 节课

§3

结构是定义的类 类键 struct;默认情况下,其成员和基础类(第10条)是公开的(第11条)。

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

值得注意的是(特别是因为提问者可能正在使用 MSVC++,因为他提到了“非托管”C++),如果使用以下方式声明类,Visual C++ 在某些情况下会抱怨: class 然后定义为 struct (或者可能反过来),尽管标准说这是完全合法的。

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

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

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

    类默认访问类型是私有的,并且继承的默认模式是私有的。应该将类用于分组在该数据上操作的数据和方法。

    简而言之,该约定是在目的是分组数据时使用struct,并在需要数据抽象以及可能的继承时使用类。

    在C ++的结构和类中,除非明确退出引用。在其他语言中,类和结构可能具有不同的语义 - 即。对象(类的实例)可以通过参考传递,结构可以按值传递。笔记:这个问题有评论。请参阅讨论页添加到对话。

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

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

和...之间的不同 classstruct 是关键字之间的差异,而不是数据类型之间的差异。这两个

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

两者都定义了类类型。此上下文中关键字的区别在于默认访问不同:

  • foo::x 是公开的并且 foo_base 被公开继承
  • bar::x 是私人的并且 bar_base 是私人继承的

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

当与大量没有班级的人一​​起开发大型项目时,您最终可能会得到复杂的耦合代码,因为每个人都使用他们想要的任何功能和数据。类提供权限控制和内在功能,以增强解耦和重用代码。

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

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

您可能会考虑将此作为何时使用 struct 或 class 的指南, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

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

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

从逻辑上讲,它代表一个单个值,类似于原始类型(INT,Double等)。

它的实例大小低于16个字节。

它是不可改变的。

它不必经常装箱。

和...之间的不同 结构体班级 C++ 中的关键字是,当特定复合数据类型没有特定说明符时,则默认情况下 结构体 或者 联盟 public 关键字仅考虑数据隐藏,而 class 是 private 关键字,考虑程序代码或数据的隐藏。总是有一些程序员使用 结构体 对于数据和 班级 为了代码的缘故。欲了解更多信息,请联系其他来源。

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

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

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

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

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

例如:

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. 我的类对象1
  2. 我的类对象2

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

因此,如果我们对 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 类型的 _myStructObject 变量中,并且
使用“_myStructObject1.DataMember = 10”将值 10 分配给结构的数据成员。

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

因此,无论我们对 _myStructObject1 进行什么更改,都不会影响 MyStructrue 类型的另一个变量 _myStructObject2。
这就是为什么我们说结构是值类型。

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

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

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

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

-> 我在类与结构中发现的另一个方便的事情是,在程序中实现文件时,如果您想在每组新操作上一次又一次地对结构进行某些操作,您需要创建一个单独的函数,并且需要从文件中读取结构体后传递该结构体对象,以便对其进行一些操作。在课堂上,如果您创建一个函数,每次都对所需的数据执行一些操作..它很容易,您只需从文件中读取对象并调用该函数..

但这取决于程序员他/她认为合适的方式...根据我的说法,我每次都更喜欢类,只是因为它支持 OOP,这就是它在几乎所有语言中实现的原因,并且它是所有时间编程的美妙功能;- )

是的,我忘记提到的最令人难忘的区别是类支持数据隐藏,并且还支持对内置数据类型执行的操作,而结构则不支持!

**更新:** 请忽略此回复。我没有考虑到该结构体的值未初始化但恰好为 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 未初始化。因此,默认构造函数对于 struct 和 struct 的作用似乎确实存在差异。班级。我在 Visual Studio 中看到了这一点。

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

1st- 内存是为堆栈内存中的结构保留的(与编程语言很接近),无论堆栈内存中的类是否仅为引用而保留,而实际内存则在堆内存中保留。

2Nd - 默认情况下,结构是否视为 public ,而类是否视为 private 。

3Rd-不能在结构中重用代码,但在类中我们可以多次重用相同的代码,称为继承

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top