c++中struct和class的区别是什么?

这个问题是在c# /的上下文中已经问过了。网

现在我想学习c++中结构体和类的区别。请讨论在OO设计中选择一种或另一种的技术差异以及原因。

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

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

我敢肯定,在c++规范的晦涩角落里还会发现其他不同之处。

361768 次浏览

类的成员默认为private。Struct的成员默认为public。除此之外,没有其他区别。也可参见这个问题

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

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

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

根据c++编程语言中的Stroustrup:

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

在功能上,除了public / private没有区别

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

这只是一种惯例。可以创建结构来保存简单的数据,但稍后会随着成员函数和构造函数的添加而发展。另一方面,在struct中看到public: access之外的东西是不寻常的。

引用c++ FAQ,

[7.8]两者之间有什么区别 关键字struct和class?< / p >

a的成员和基类 结构默认为public,而在 类时,它们默认为private。注意: 你应该创建基类 明确地公开、私有或 被保护,而不是依靠 违约。< / p >

Struct和class则不然 功能上等价的。< / p >

好了,够干净了 电子说话。在情感上,最 开发人员做出了强烈的区分 在类和结构之间。一个 Struct感觉就像一个开放的堆 只有很少的部分 封装或功能。一个 上课就像一种生活 有责任感的社会成员 智能服务,实力强大 封装屏障,且封井 定义接口。因为这是 大多数人已经拥有的内涵, 你可能应该使用结构体 关键字,如果你有一个类 方法很少,有公共数据 (这样的事情确实存在于精心设计的地方 系统!),但除此之外,你应该 可能使用class关键字

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

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

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

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

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

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

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

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

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

  1. 结构的成员默认为public,类的成员默认为private。
  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上。

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

引用标准(§11.2.2在c++ 98到c++ 11):

如果没有访问说明符 对于基类,假定为public 当声明派生类时 struct和private在类声明为时被假设。

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

类定义的类的成员 关键字私人 by 违约。定义的类的成员 使用关键字结构体联盟

另一个区别是:关键字class可以用于声明模板参数,而关键字struct不能这样使用。

Iso iec14882 -2003

9类

§3

结构是用定义的类 类关键 struct;它的成员 基类(第10条)是

.默认为Public(第11条)

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

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

在采用面向对象的方法时,默认为public通常被认为是一个坏主意,所以在编写一种原生有利于OOP(你可以在C中做OO,但它不会帮助你)的C形式时,这是c++(最初是“C With Classes”)的想法,默认为private成员是有意义的。

另一方面,如果Stroustrup改变了struct的语义,使其成员默认为私有,则会破坏兼容性(随着标准的分歧,这种情况不再经常发生,但所有有效的C程序也是有效的c++程序,这对给予c++立足之处有很大影响)。

因此,引入了一个新的关键字class,使其完全类似于结构体,但默认为private。

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

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

我发现了另一个不同点。如果在类中没有定义构造函数,编译器将定义一个。但是在struct中,如果你没有定义构造函数,编译器也不会定义构造函数。因此,在某些情况下,我们确实不需要构造函数,struct是一个更好的选择(性能技巧)。

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

值得注意的是(特别是因为他提到了“非托管”c++,所以请求者很可能正在使用msvc++),在某些情况下,如果一个类是用class声明的,然后用struct定义的(或者相反),Visual c++会抱怨,尽管标准说这是完全合法的。

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
    <李> < p >。在类中,所有成员默认为private,但在结构中

    .成员默认为public
    1. 对于结构体,没有构造函数和析构函数这样的术语,但对于类,如果不提供,编译器将创建默认值。

    2. Sizeof空结构是0字节,而Sizeof空类是1字节结构的默认访问类型是public。结构体应该 通常用于分组数据。李< / p > < / >

    类的默认访问类型是private,默认模式为 继承是私人的。类应该用于分组数据和 操作该数据的方法。< / p > 简而言之,约定是当目的是…时使用struct 分组数据,并在需要数据抽象时使用类, 也许继承。< / p > 在c++中,除非显式地传递,否则结构和类是按值传递的 强制转换。在其他语言中,类和结构可能有 不同的语义——即。可以传递对象(类的实例) 通过引用和结构可以通过值传递。注:有 与这个问题相关的评论。参见讨论页

    .加入对话

c++中结构体关键字的区别在于,当在特定的复合数据类型上没有特定的说明符时,默认情况下结构体联盟是只考虑隐藏数据的公共关键字,而class是考虑隐藏程序代码或数据的私有关键字。总是有些程序员使用结构体来处理数据,使用来编写代码。欲了解更多信息,请联系其他渠道。

综上所述,我们可以得出结论,概念Class比“Structures”更适合代表现实世界中的对象。很大程度上是因为在课堂上使用的面向对象的概念在解释现实场景时非常实用,因此更容易将它们合并到现实中。例如,对于结构体,默认继承是公共的,但如果我们将此规则应用于现实世界,那就太荒谬了。但在类中,默认继承是私有的,这更现实。

无论如何,我需要证明的是类是一个更广泛的,现实世界适用的概念,而结构是一个原始的概念,具有糟糕的内部组织(即使结构遵循面向对象的概念,他们有一个糟糕的含义)

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

例如:

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

在main方法中,
我可以使用new操作符创建该类的实例,为该类
分配内存 并将其基址存储到MyClass类型变量(_myClassObject2)中。< / p >

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

将指向相同的内存位置 它基本上是将相同的内存位置赋给另一个相同类型的变量 因此,如果我们在MyClass类型的任何一个对象中所做的任何改变都会对另一个对象产生影响 因为两者都指向相同的内存位置 < p > " _myClassObject1。DataMember = 10;"在这一行,对象的两个数据成员都包含10的值 “_myClassObject2。DataMember = 20;"在这一行,对象的数据成员都将包含20的值 最终,我们通过指针访问对象的数据成员。 < / p > 与类不同,结构是值类型。 例如:

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 "将值10赋给结构的数据成员。DataMember = 10”。< / p >

在下一行中,
我声明了另一个MyStructure类型的变量_myStructObject2,并将_myStructObject1赋值给它。< br > 这里。net c#编译器创建了_myStructureObject1对象和
的另一个副本 将该内存位置分配给MyStructure变量_myStructObject2 所以无论我们对_myStructObject1做什么改变,都不会对另一个MyStructrue类型的变量_myStructObject2产生影响。< br > 这就是为什么我们说结构是值类型。

所以class的直接基类是Object, Structure的直接基类是继承自Object的ValueType 类将支持继承,而结构则不支持

我们怎么这么说?< br > 这背后的原因是什么?< br > 答案是类。< br > < / p >

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

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

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

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

默认情况下,结构对待公共类是否对待私有类。

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

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

当与大量的人一起开发大型项目时,你可能最终会得到复杂的耦合代码,因为每个人都使用他们想要的函数和数据。类提供权限控制和固有属性,以增强代码的解耦和重用。

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

顺便说一句,当一个struct分配了大量内存并包含了几个变量时,值类型变量表示值嵌入到struct分配的位置。相比之下,引用类型变量的值是外部的,由一个指针引用,该指针也嵌入在struct分配的地方。

你可以考虑用它来指导什么时候使用struct或类https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx

类的实例,考虑定义一个结构体而不是类 类型小,通常寿命短或通常嵌入 其他对象。< / p > 避免定义struct,除非类型中包含所有的 以下特征:

逻辑上代表一个值, 类似于基本类型(int, double等)

它有一个实例

. Size小于16字节

它是不可变的。

它不需要被装箱 频繁。< / p >

  1. 类的成员是默认为私有, struct的成员是默认为Public

例如,程序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;
}
// 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;
}
  1. 当从类/结构体派生结构体时,基类/结构的默认访问说明符是public.;派生类时,默认访问说明符是私有的.;

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

// Program 3
#include <stdio.h>
 

class Base {
public:
int x;
};
 

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

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

class Base {
public:
int x;
};
 

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

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

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

这意味着如果你想要编写一个与C兼容的头文件,那么除了struct(在C世界中不能有函数;但可以有函数指针)。

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

我在class vs struct中发现的另一个方便的事情是,当在程序中实现文件时,如果你想在每一组新的操作上一次又一次地对struct进行一些操作,你需要创建一个单独的函数,并且你需要在从文件中读取struct后传递object of struct,以便对它进行一些操作。 在课堂上,如果你创建了一个函数,每次都对所需的数据进行一些操作,这很简单,你只需要从文件中读取object并调用函数..

但这取决于程序员认为哪种方式合适……对我来说,我更喜欢类,因为它支持oop,这就是它几乎在所有语言中实现的原因,它是所有编程的美妙特性;-)

是的,我忘记提到的最令人难忘的区别是类支持数据隐藏,也支持在内置数据类型上执行的操作,而struct不支持!

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

  2. 如果基类没有访问说明符,则当派生的类声明为struct时假定为public,当类声明为class时假定为private

  3. 你可以使用template<class T>,但不能使用template<struct T>

还要注意,c++标准允许将类型前向声明为struct,然后在声明类型时使用class,反之亦然。同样,对于Y是structclassstd::is_class<Y>::valuetrue,但是对于enum classfalsefalse

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

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

两者都定义了一个类类型。这里关键字的区别在于默认访问权限的不同:

  • foo::x是公共的,而foo_base是公共继承的
  • bar::x是私有的,bar_base是私有继承的
还有一个不成文的规则告诉我们: 如果类的数据成员与自身没有关联,则使用struct。 如果数据成员的值依赖于另一个数据成员的值,则使用class.

f.e

class Time
{
int minutes;
int seconds;
}


struct Sizes
{
int length;
int width;
};