首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我们应该在结构中添加构造函数吗?

我们应该在结构中添加构造函数吗?
EN

Software Engineering用户
提问于 2014-11-11 16:51:49
回答 3查看 46K关注 0票数 16

我们通常使用c++结构来定义数据结构,而不是类,类可以是一个包含成员方法的完整模块。在内心深处,我们知道他们都是一样的(松散地说)。

我们经常将结构作为数据实体使用/处理,这就产生了这样的冲动,即我们也没有添加默认的构造函数。但是构造函数总是很棒的,它们使事情变得更简单,并有助于消除错误。

如果将默认构造函数添加到我的数据结构中,它会被拒绝吗?

如果满足其他条件,实现默认构造函数是否也会使结构非POD(普通旧数据类型)?

要正确地看待问题,请考虑一个简单的例子,但在现实中,结构要大得多。

代码语言:javascript
复制
struct method
{
    char    name[32];
    float   temperature;
    int     duration;
};

每次我创建一个方法时,我都要担心(至少可以说),如果我忘记设置一些值。想象一下,我忘记设置temperature并将该方法应用于系统,这是一个随机的高值,并造成混乱。或者我忘了设置duration,现在该方法应用于一个未知的高持续时间。

为什么我要承担每次初始化对象的责任,而不是实现它的构造函数来保证它呢?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2014-11-11 17:29:36

有时将构造函数添加到结构中是合适的,但有时却不是。

向结构中添加构造函数(任何构造函数)可防止在其上使用聚合初始化器。因此,如果添加默认构造函数,还必须定义初始化值的非默认构造函数。但是,如果要确保始终初始化所有成员,则这是适当的。

添加构造函数(同样,任何构造函数)使其非POD,但在C++11中,以前只应用于POD的大多数规则都被更改为适用于标准布局对象,而添加构造函数不会破坏这一点。因此,聚合初始化程序基本上是您丢失的唯一东西。但这也往往是一个巨大的损失。

票数 14
EN

Software Engineering用户

发布于 2014-11-13 16:08:23

你可以做的C++11

代码语言:javascript
复制
struct method
{
    char    name[32] {};
    float   temperature = 42.141521;
    int     duration = -6;
};

每当您忘记初始化某些内容时,就会得到默认的初始化。

票数 8
EN

Software Engineering用户

发布于 2014-11-11 18:45:51

快速回答:

这取决于你想要实现什么。

长长的,扩展的,无聊的答案:

你打到钉子了。

我通常不喜欢"C++“允许"Struct (s)”允许声明方法。我最好对所需的方法和P.O.D使用显式的"Class (es)“。“结构(s)”只适用于田园。

然而,我同意一些基本的简单操作,例如:

  • 赋值初始值(“构造函数”)
  • 创建结构的副本(“复制构造函数”)
  • 为现有结构赋值(“重载赋值运算符”)

是必需的,在这种情况下,结构的方法是有意义的。

建议

另一种可能的解决方案是使用P.O.D.结构,但在概念上仍然将它们视为类和对象。

将这些声明包装在命名空间中,并为最重要的操作添加全局函数。

代码声明可以类似于以下内容:

代码语言:javascript
复制
namespace Customers
{
  struct CustomerStruct
  {
    char[255] FirstName;
    char[255] LastName;
    int Age;
    bool IsAlive;
    bool IsMarried;
  }; // struct

  CustomerStruct* CreateCustomer
  (
    char* NewFirstName;
    char* NewLastName;
    int NewAge;
    bool NewIsAlive;
    bool NewIsMarried;
  )
  {
    CustomerStruct* NewCustomer = new CustomerStruct();
      NewCustomer->FirstName = NewFirstName;
      NewCustomer->LastName = NewLastName;
      NewCustomer->Age = NewAge;
      NewCustomer->IsAlive = NewIsAlive;
      NewCustomer->IsMarried = NewIsMarried;
    return NewCustomer;
  } // CustomerStruct* CreateCustomer (...)

} // namespace

应用解决方案的代码可能如下所示:

代码语言:javascript
复制
#include <Customers>

using Customers;

int main (...)
{
   int ErrorCode = 0;

   CustomerClass* ThisCustomer =
     Customers::CreateCustomer
      ("John", "Doe", 23, true, true);

   // do something with "ThisCustomer"

   delete ThisCustomer;

   return ErrorCode;
} // int main(...)

当需要大量内存分配数据或与其他低级别共享库交互时,这种替代方法更好。

这种方法在游戏开发中得到了一定的改变。

额外

就我个人而言,我认为是"C++“的语法扩展,甚至是一个新的基于"C++”的P.L.,它解决了这个问题:

代码语言:javascript
复制
// "Plain Old Data" Structure
// No Methods, No "Functors", allowed
strict struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;
}; // strict struct

// Object Oriented "Plain Old Data" Structure
// Yes, Methods and "Functors" allowed
relaxed struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;

  public void Foo();
  public void Bar();

  public (void*) (SomeFunctor) ();
}; // relaxed struct

// Class and Object Oriented
class CustomerClass
{
  public char[255] FirstName;
  public char[255] LastName;
  public int Age;
  public bool IsAlive;
  public bool IsMarried;

  public void Foo();
  public void Bar();
}; // class

干杯。

票数 -1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/262463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档