什么时候应该在C ++中使用类vs结构?

c++ oop class struct ooad

367688 观看

24回复

4516 作者的声誉

在什么情况下在C ++中使用structvs a 更好class

作者: Alan Hinchcliffe 的来源 发布者: 2008 年 9 月 10 日

回应 24


724

24091 作者的声誉

决定

C ++中a class和a 之间的差异struct是结构具有默认public成员,而基础和类具有默认private成员和基础。两个类和结构可具有的混合物publicprotectedprivate构件,可以使用继承并且可以具有成员函数。

我建议使用结构作为普通旧数据结构而不使用任何类类特性,并使用类作为具有private数据和成员函数的聚合数据结构。

作者: Commodore Jaeger 发布者: 2008 年 9 月 10 日

8

25692 作者的声誉

对于C ++,结构和类之间确实没有太大的区别。主要功能区别在于,默认情况下结构的成员是公共的,而在类中默认是私有的。否则,就语言而言,它们是等价的。

也就是说,我倾向于像在C#中一样使用C ++中的结构,类似于Brian所说的。结构是简单的数据容器,而类用于需要对数据执行操作的对象,而不仅仅是保持数据。

作者: Andy 发布者: 2008 年 9 月 10 日

4

285 作者的声誉

它们几乎是一回事。感谢C ++的神奇之处,一个struct可以保存函数,使用继承,使用“new”创建,就像一个类一样

唯一的功能区别是一个类以私有访问权限开头,而一个结构以public开头。这是与C保持向后兼容性。

在实践中,我总是使用结构作为数据持有者和类作为对象。

作者: enigmatic 发布者: 2008 年 9 月 10 日

21

1301 作者的声誉

结构对我有用的一个地方就是我有一个系统从另一个系统接收固定格式的消息(比如说,一个串口)。您可以将字节流强制转换为定义字段的结构,然后轻松访问字段。

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

显然,这与你在C中做的一样,但我发现必须将消息解码为类的开销通常是不值得的。

作者: mbyrne215 发布者: 2008 年 9 月 10 日

7

4516 作者的声誉

回答我自己的问题(无耻地),如前所述,访问权限是C ++中它们之间的唯一区别。

我倾向于仅使用结构进行数据存储。如果它更容易处理数据,我将允许它获得一些辅助函数。但是,只要数据需要流控制(即维护或保护内部状态的getter / setter)或开始获取任何主要功能(基本上更像对象),它就会“升级”到类以更好地传达意图。

作者: Alan Hinchcliffe 发布者: 2008 年 9 月 10 日

9

694 作者的声誉

当您使用C ++实现提供C兼容接口时,Structs(更一般地说是POD)很方便,因为它们可以跨语言边界和链接器格式移植。

如果你不关心这一点,那么我认为使用“struct”代替“class”是一个很好的意向沟通者(正如@ZeroSignal所说)。结构也具有更可预测的复制语义,因此它们对于您打算写入外部媒体或通过线路发送的数据非常有用。

结构对于各种元编程任务也很方便,比如只显示一堆依赖类型构造的特征模板:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

......但这真的只是利用struct的默认保护级别是公开的......

作者: argv0 发布者: 2008 年 9 月 10 日

-6

4285 作者的声誉

我从不在C ++中使用“struct”。

我想不到你想要私人会员时使用结构的场景,除非你故意让人感到困惑。

似乎使用结构更多地是关于如何使用数据的语法指示,但我宁愿只创建一个类并尝试在类的名称或通过注释进行显式化。

例如

class PublicInputData {
    //data members
 };
作者: Baltimark 发布者: 2008 年 9 月 10 日

53

82256 作者的声誉

我唯一一次使用struct而不是类是在函数调用中使用它之前声明一个仿函数,并且为了清晰起见希望最小化语法。例如:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 
作者: Ferruccio 发布者: 2008 年 9 月 10 日

2

53152 作者的声誉

它们具有不同的默认值(默认情况下为私有,默认情况下为classpublic struct),因此理论上它们完全可以互换。

所以,如果我只想打包一些信息来移动,我使用一个结构,即使我在那里放了几个方法(但不是很多)。如果它是一个大多数不透明的东西,主要用途是通过方法,而不是直接对数据成员,我使用完整的类。

作者: Javier 发布者: 2009 年 7 月 28 日

2

5651 作者的声誉

默认情况下,结构具有公共访问权限,默认情况下类具有私有访问权限。

我个人使用数据传输对象的结构或值对象。当我这样使用时,我将所有成员声明为const以防止被其他代码修改。

作者: anio 发布者: 2009 年 7 月 28 日

204

13008 作者的声誉

正如其他人所指出的那样,实际上只存在两种语言差异:

  • struct默认为公共访问,class默认为私人访问。
  • 继承时,struct默认为public继承,class默认为private继承。(具有讽刺意味的是,与C ++中的许多内容一样,默认是向后的:public继承是迄今为止更常见的选择,但人们很少声明struct只是为了节省输入“ public”关键字。

但在实践中,真正的差别是间class/ struct声明构造函数/析构函数不和的。对于“普通旧数据”POD类型有一定的保证,一旦你接管了类的构造,它就不再适用了。为了清楚地区分这种区别,许多人故意仅将structs用于POD类型,如果他们要添加任何方法,请使用classes。下面两个片段之间的区别是没有意义的:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(顺便提一下,这里有一个关于“POD类型”实际含义的一些好解释的线程:C ++中的POD类型是什么?

作者: quark 发布者: 2009 年 7 月 28 日

34

5940 作者的声誉

C ++ FAQ Lite

结构的成员和基类默认是公共的,而在类中,它们默认为private。注意:您应该明确公开,私有或保护基类,而不是依赖于默认值。

struct和class在功能上是等价的。

好的,足够的那个干净的技术谈话。在情感上,大多数开发人员在类和结构之间做出了很强的区分。结构只是感觉像一堆开放的位,几乎没有封装或功能。课程感觉像是一个生活和负责任的社会成员,拥有智能服务,强大的封装屏障和明确的界面。既然这是大多数人已经拥有的内涵,那么你应该使用struct关键字,如果你有一个方法很少且有公共数据的类(这些东西确实存在于设计良好的系统中!),否则你应该使用这个类关键词。

作者: Tal Pressman 发布者: 2009 年 7 月 28 日

-4

946 作者的声誉

我认为Structs旨在作为数据结构(如多数据类型的信息数组),并且类用于代码打包(如子程序和函数的集合)。

:(

作者: GaiusSensei 发布者: 2009 年 7 月 28 日

0

331 作者的声誉

我只在需要保存一些数据而没有任何与之关联的成员函数(对成员数据进行操作)并直接访问数据变量时才使用struct。

例如:从文件和套接字流等读取/写入数据。在函数参数太多而函数语法看起来过于冗长的结构中传递函数参数。

从技术上讲,除了默认可访问性之外,类和结构之间没有很大的区别。更多内容取决于编程风格如何使用它。

作者: harik 发布者: 2009 年 7 月 28 日

1

9234 作者的声誉

从技术上讲,两者在C ++中是相同的 - 例如,结构可能有重载运算符等。

但是:

当我希望同时传递多种类型的信息时,我使用结构我在处理“功能”对象时使用类。

希望能帮助到你。

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

例如,我在这里的get ...()方法中返回一个struct学生 - 享受。

作者: Maciek 发布者: 2009 年 7 月 28 日

15

305 作者的声誉

正如每个人所说,唯一真正的区别是默认访问。但是当我不希望使用简单的数据类进行任何类型的封装时,我特别使用struct,即使我实现了一些辅助方法。例如,当我需要这样的东西时:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};
作者: ogoid 发布者: 2009 年 7 月 28 日

1

66974 作者的声誉

您何时会选择使用struct以及何时在C ++中使用类?

struct在定义functors和使用时使用POD。否则我用class

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};
作者: AraK 发布者: 2009 年 7 月 28 日

16

5464 作者的声誉

如果要编写内部为C ++但可以通过C或C ++代码调用API的库,则可以在C ++中使用“struct”。您只需创建一个包含结构和全局API函数的标头,并将这些函数公开给C和C ++代码,如下所示:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

然后,您可以使用C ++代码在C ++文件中编写函数bar(),并使其可以从C调用,并且两个世界可以通过声明的struct共享数据。当然,在混合C和C ++时还有其他注意事项,但这是一个简化的例子。

作者: Adisak 发布者: 2009 年 10 月 27 日

142

309294 作者的声誉

现有答案中存在许多误解。

两者classstruct宣布一个班级。

是的,您可能必须在类定义中重新排列访问修改关键字,具体取决于您用于声明类的关键字。

但是,除了语法之外,选择一个而不是另一个的唯一原因是约定/样式/偏好。

有些人喜欢在struct没有成员函数的情况下坚持使用关键字,因为结果定义“看起来像”来自C的简单结构。

类似地,有些人喜欢将class关键字用于具有成员函数和private数据的类,因为它上面写着“类”,因此看起来就像他们最喜欢的面向对象编程的书中的例子。

现实情况是,这完全取决于您和您的团队,这对您的计划来说几乎没有任何区别。

除了名称之外,以下两个类绝对等同于:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

您甚至可以在重新声明时切换关键字:

class Foo;
struct Bar;

(尽管由于不符合性而导致Visual Studio构建中断,因此编译器会在您执行此操作时发出警告。)

并且以下表达式都评估为true:

std::is_class<Foo>::value
std::is_class<Bar>::value

但请注意,重新定义时无法切换关键字; 这只是因为(根据单一定义规则)跨翻译单元的重复类定义必须“由相同的标记序列组成”。这意味着你甚至无法交流const int member;int const member;,并有无关的语义classstruct

作者: Lightness Races in Orbit 发布者: 2016 年 4 月 28 日

1

938 作者的声誉

当我需要创建POD类型或仿函数时,我使用结构。

作者: ivan.ukr 发布者: 2016 年 9 月 15 日

3

293 作者的声誉

类。

默认情况下,类成员是私有的。

class test_one {
    int main_one();
};

相当于

class test_one {
  private:
    int main_one();
};

所以,如果你尝试

int two = one.main_one();

我们会收到一个错误:main_one is private因为它无法访问。我们可以通过指定它的公共ie来初始化它来解决它

class test_one {
  public:
    int main_one();
};

结构。

struct是一个默认情况下成员是公共的类。

struct test_one {
    int main_one;
};

手段main_one是私人的,即

class test_one {
  public:
    int main_one;
};

我将结构用于数据结构,其中成员可以获取任何值,这样更容易。

作者: Frrank 发布者: 2017 年 11 月 7 日

2

3459 作者的声誉

An advantage of struct over class is that it save one line of code, if adhering to "first public members, then private". In this light, I find the keyword class useless.

Here is another reason for using only struct and never class. Some code style guidelines for C++ suggest using small letters for function macros, the rationale being that when the macro is converted to an inline function, the name shouldn't need to be changed. Same here. You have your nice C-style struct and one day, you find out you need to add a constructor, or some convenience method. Do you change it to a class? Everywhere?

区分structs和classes是太麻烦了,妨碍我们应该做的事情 - 编程。像许多C ++的问题一样,它源于对向后兼容性的强烈渴望。

作者: Vorac 发布者: 2017 年 11 月 14 日

1

440 作者的声誉

正如其他人所指出的那样

  • 除默认可见性外,两者都是等效的
  • 可能有理由因任何原因被迫使用这一个或另一个

有关何时使用Stroustrup / Sutter的明确建议:

如果类具有不变量,请使用类; 如果数据成员可以独立变化,请使用struct

但是,请记住,转发声明是不明智的。作为class(class X;)并将其定义为struct(struct X { ... })。它可能适用于某些链接器(例如,g ++)并且可能在其他链接器上失败(例如,MSVC),因此您将发现自己处于开发人员的地狱中。

作者: pasbi 发布者: 2018 年 9 月 17 日

1

146 作者的声誉

默认情况下,所有类成员都是私有的,并且所有struct成员都是公共的。类具有默认私有基础,而Struct具有默认公共基础。在C的情况下,struct不能具有成员函数,在C ++的情况下,我们可以将成员函数添加到结构中。除了这些差异,我没有发现任何令人惊讶的事情。

作者: Helping Bean 发布者: 2018 年 10 月 15 日
32x32