在c++中,在哪些情况下使用结构体比使用类更好?
当前回答
现有的答案中有很多误解。
class和struct都声明一个类。
是的,您可能必须在类定义中重新安排访问修改关键字,这取决于您用于声明类的关键字。
但是,除了语法之外,选择一种而不是另一种的唯一原因是惯例/风格/偏好。
有些人喜欢对没有成员函数的类坚持使用struct关键字,因为最终的定义“看起来像”C中的简单结构。
类似地,有些人喜欢对具有成员函数和私有数据的类使用class关键字,因为它表示“类”,因此看起来像他们最喜欢的面向对象编程书籍中的示例。
实际上,这完全取决于您和您的团队,这对您的程序没有任何影响。
下面这两个类除了名字以外在其他方面都是完全等价的:
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成员;,并且与类或结构的语义无关。
其他回答
我唯一一次使用结构体而不是类是在函数调用中使用函数子之前声明函数子,为了清晰起见,我想尽量减少语法。例如:
struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare());
回答我自己的问题(无耻地),正如已经提到的,访问权限是c++中它们之间的唯一区别。
我倾向于仅将结构体用于数据存储。我将允许它获得一些帮助函数,如果它使处理数据更容易的话。然而,一旦数据需要流控制(即维护或保护内部状态的getter /setter)或开始获得任何主要功能(基本上更像对象),它将被“升级”为一个类,以更好地传达意图。
默认情况下,结构具有公共访问权限,类具有私有访问权限。
就我个人而言,我使用结构作为数据传输对象或作为值对象。当这样使用时,我将所有成员声明为const,以防止其他代码修改。
正如其他人指出的那样
除了默认可见性之外,两者都是等效的 无论出于什么原因,都可能有理由被迫使用其中一种或另一种
关于何时使用Stroustrup/Sutter给出了明确的建议:
如果类有不变量,则使用class;如果数据成员可以独立变化,则使用struct
然而,请记住,将某事物前向声明为类(class X;)并将其定义为struct (struct X{…})。 它可能在某些链接器上工作(例如g++),但可能在其他链接器上失败(例如MSVC),所以你会发现自己陷入了开发人员的地狱。
现有的答案中有很多误解。
class和struct都声明一个类。
是的,您可能必须在类定义中重新安排访问修改关键字,这取决于您用于声明类的关键字。
但是,除了语法之外,选择一种而不是另一种的唯一原因是惯例/风格/偏好。
有些人喜欢对没有成员函数的类坚持使用struct关键字,因为最终的定义“看起来像”C中的简单结构。
类似地,有些人喜欢对具有成员函数和私有数据的类使用class关键字,因为它表示“类”,因此看起来像他们最喜欢的面向对象编程书籍中的示例。
实际上,这完全取决于您和您的团队,这对您的程序没有任何影响。
下面这两个类除了名字以外在其他方面都是完全等价的:
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成员;,并且与类或结构的语义无关。
推荐文章
- cplusplus.com给出的错误、误解或坏建议是什么?
- 找出质数最快的算法是什么?
- 如何在方法中访问“静态”类变量?
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 在函数的签名中添加关键字
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?