关于OOP:什么时候在C++中使用类和结构?

When should you use a class vs a struct in C++?

在什么情况下,在C++中使用EDCOX1的0度与EDCOX1的1度更好?


在C++中,EDCOX1与0的EDCOX1和1之间的区别在于,结构具有默认EDCOX1,2个成员和基,并且类具有默认EDCOX1,3个成员和基。类和结构都可以混合使用publicprotectedprivate成员,可以使用继承,也可以具有成员函数。

我建议将结构用作没有类特性的普通旧数据结构,并将类用作具有private数据和成员函数的聚合数据结构。


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

  • struct默认为公共访问,class默认为私有访问。
  • 继承时,struct默认为public继承,class默认为private继承。(具有讽刺意味的是,与C++中的许多事物一样,默认是反向的:EDCOX1×5继承是迄今为止更常见的选择,但是人们很少声明EDOCX1×1"s只是为了节省键入"EDCOX1×5"关键字。

但实际中的真正区别在于声明构造函数/析构函数的class和不声明构造函数/析构函数的struct之间。对"普通旧数据"pod类型有一定的保证,一旦接管类的构造,就不再适用。为了保持这一区别,许多人故意只将struct用于pod类型,如果要添加任何方法,则使用classes。以下两个片段之间的差异在其他方面毫无意义:

1
2
3
4
5
6
7
8
9
10
11
class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(顺便说一句,这里有一个关于"POD类型"实际上意味着什么的线索:C++中的POD类型是什么?


在现有的答案中有很多误解。

classstruct都声明一个类。

是的,您可能需要重新排列访问权限,修改类定义中的关键字,这取决于您用于声明类的关键字。

但是,除了语法之外,选择其中一个的唯一原因是约定/样式/首选项。

有些人喜欢为没有成员函数的类使用struct关键字,因为产生的定义"看起来"像是C中的一个简单结构。

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

事实上,这完全取决于你和你的团队,而且这对你的计划毫无影响。

以下两个类在各个方面都是完全等效的,除了它们的名称:

1
2
3
4
5
6
7
8
9
10
struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

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

1
2
class Foo;
struct Bar;

(尽管这会由于不一致性而中断Visual Studio生成,因此在执行此操作时编译器将发出警告。)

以下表达式的值均为真:

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

但是请注意,在重新定义时不能切换关键字;这只是因为(根据一个定义规则)跨翻译单元的重复类定义必须"由相同的令牌序列组成"。这意味着你甚至不能与int const member;交换const int member;,与classstruct的语义无关。


我唯一一次使用结构而不是类是在函数调用中使用前声明一个函数,为了清晰起见,我想最小化语法。例如。:

1
2
struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare());


从C++ FAQ Lite:

The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.

struct and class are otherwise functionally equivalent.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.


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

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

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

显然,这与您在C中所做的相同,但我发现将消息解码为类的开销通常是不值得的。


如果你正在编写一个内部是C++的库,但是API可以用C或C++代码调用,那么你可以在C++中使用"Stult"。您只需创建一个包含结构和全局API函数的单个头,您可以同时向C和C++代码公开这些函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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中调用,并且两个世界可以通过声明的结构共享数据。当然,在混合C和C++时还有其他的注意事项,但这是一个简化的例子。


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

1
2
3
4
5
6
7
struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};


结构(POD,更一般)是方便的,当你提供一个C兼容的接口与C++实现,因为它们是跨语言边界和链接器格式的便携式。

如果您不关心这一点,那么我想使用"struct"而不是"class"是一个很好的意图传达工具(如上面所说的@zerosignal)。结构还具有更可预测的复制语义,因此它们对于要写入外部媒体或通过网络发送的数据很有用。

结构对于各种元编程任务也很方便,比如只公开一系列依赖typedef的特征模板:

1
2
3
4
5
template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

…但这实际上只是利用了struct的默认保护级别为public…


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

也就是说,我倾向于使用C++中的结构,就像我在C语言中使用的,类似于布瑞恩所说的。结构是简单的数据容器,而类用于对象,这些对象除了保留数据之外还需要对数据进行操作。


为了回答我自己的问题(无耻地),正如已经提到的,访问权限是它们在C++中唯一的区别。

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


它们几乎是一样的。由于C++的魔力,结构可以像类一样保存函数、使用继承、使用"新"等来创建。

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

在实践中,我总是使用结构作为数据容器,使用类作为对象。


班级。

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

1
2
3
class test_one {
    int main_one();
};

等于

1
2
3
4
class test_one {
  private:
    int main_one();
};

所以如果你尝试

1
int two = one.main_one();

我们会得到一个错误:main_one is private,因为它不可访问。我们可以通过指定它的公共IE来初始化它来解决问题

1
2
3
4
class test_one {
  public:
    int main_one();
};

结构。

结构是成员默认为公共的类。

1
2
3
struct test_one {
    int main_one;
};

意味着main_one是私有的IE

1
2
3
4
class test_one {
  public:
    int main_one;
};

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


class相比,struct的一个优点是它节省了一行代码,如果坚持"先是公共成员,然后是私有成员"。从这个角度来看,我发现关键字class是无用的。

这是仅使用struct而不使用class的另一个原因。C++的一些代码风格指南建议使用函数宏的小写字母,其理由是当宏被转换为内联函数时,不应该更改名称。彼此彼此。有一天,你发现你需要添加一个构造函数,或者一些方便的方法。你把它换成一个class?到处都是?

区分structs和classes实在是太麻烦了,我们要做的事情就是编程。与C++的许多问题一样,它是出于对向后兼容性的强烈愿望。


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

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


在不同的违约情况下,它们是相同的(class的违约是私有的,struct的违约是公共的),因此理论上它们是完全可互换的。

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


正如其他人指出的那样

  • 除了默认可见性外,两者都是等效的
  • 无论出于什么原因,可能有理由被迫使用其中一个或另一个

关于何时使用,有一个明确的建议,来自stroustrup/sutter:

Use class if the class has an invariant; use struct if the data members can vary independently

但是,请记住,将某事物向前声明为类(class X;)并将其定义为结构(struct X { ... })是不明智的。它可能在某些链接器(例如,G++)上工作,也可能在其他链接器(例如,MSVC)上失败,因此您将发现自己身处开发人员的地狱。


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


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


从技术上讲,C++中都是相同的,例如,结构可能有重载操作符等。

然而:

当我希望同时传递多种类型的信息时,使用结构我在处理"函数"对象时使用类。

希望它有帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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 student…()方法-享受。


When would you choose to use struct
and when to use class in C++?

当我定义functorsPOD时,我使用struct。否则我用class

1
2
3
4
5
6
7
8
9
10
11
12
13
// '()' 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; }
};


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

从文件和套接字流等读取/写入数据。在函数参数太多且函数语法太长的结构中传递函数参数。

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


我认为结构是作为数据结构(像一个多数据类型的信息数组)而设计的,类是为代码打包而集成的(像子程序和函数的集合)。

:(


我从不在C++中使用"结构"。

我无法想象当您想要私有成员时会使用一个结构的场景,除非您故意试图混淆。

似乎使用结构更像是对数据使用方式的句法指示,但我宁愿创建一个类,并尝试以类的名义或通过注释将其显式化。

例如。

1
2
3
class PublicInputData {
    //data members
 };