【问题标题】:typedef struct with pointer and constructor带有指针和构造函数的 typedef 结构
【发布时间】:2016-06-30 22:26:58
【问题描述】:

我正在写一个struct _Point3d 并将其类型定义为Point3d,并在Point3d 旁边提供了一个指针声明PPoint3d(请参阅代码)。有一个构造函数初始化struct 的成员。我在这里有两个疑问。

typedef struct _Point3d
{
    float x;
    float y;
    float z;

    _Point3d(float _x, float _y, float _z) : x(_x), y(_y), z(_z)
    {

    }

}Point3d, *PPoint3d;

一个: 这种在结构名称(typedef)之后提供指针的约定到底意味着什么?前提是我们可以像这样创建Point3d 的指针

Point3d* _ppoint2 = new Point3d(1.0, 0.0, 0.0);

两个: 这两种不同的方式创建Point3d的实例有什么区别吗?

PPoint3d _ppoint1 = new Point3d(0.0, 1.0, 0.0);
Point3d* _ppoint2 = new Point3d(1.0, 0.0, 0.0);

【问题讨论】:

  • 1) 我认为这里的指针类型定义是不喜欢语言语法的怪人的工作。 2)没有区别。 3) 保留全局命名空间中以下划线开头的名称。
  • 当你使用new时,为什么这个标签是C?如果这仅适用于 C++,则声明不遵循 C++ 声明和使用类的约定。
  • 实际上我根本看不到在这里使用 typedef 的意义。恕我直言,写struct Point3d { float x,y,z;} 更简单、更清晰,不需要typedef
  • 你以前写过很多C代码吧?所以,忘掉一切,像学习一门新语言一样学习 C++

标签: c++ pointers struct typedef


【解决方案1】:

我正在编写一个 struct _Point3d 并将其定义为 Point3d 并在 Point3d 旁边提供了一个指针声明 *PPoint3d

停在那里,孩子。这是 2016 年,而不是 1997 年。无需再遵循神秘的微软实践。

改为这样做:

struct Point3d
{
    float x;
    float y;
    float z;

    Point3d(float _x, float _y, float _z) : x(_x), y(_y), z(_z)
    {

    }
};

using PPoint3d = std::unique_ptr<Point3d>;
using SharedPoint3d = std::shared_ptr<Point3d>;

原始指针将用于低级实现。当用作界面的一部分时,它们会使您的代码容易被用户的意外和未被注意到的错误所劫持。

因此,当用作接口的一部分时,它们是邪恶的。太邪恶了,甚至向你的班级的用户暗示他们应该使用它们都是邪恶的。

【讨论】:

  • 我们能否摆脱“原始指针是如此邪恶”的问题。非拥有的原始指针没有任何问题。
  • @StoryTeller std::experimental:: observer_ptr 存在的原因正是因为原始指针是邪恶的,尤其是当用作观察者时,仅仅是因为用户可能会错误地劫持它们。
  • @StoryTeller 你是对的。语言特性本身是必要的并且“不是邪恶的”,但将其用作界面的一部分当然是必要的。我会更新答案。
  • @A.B.我假设您的意思是在使用 C++ 程序中的 C 功能时?我鼓励您尽早将 C 指针包装在 C++ 智能指针中。智能指针的自定义删除器使这在每种情况下都成为可能。
  • @A.B. win32 API 很久以前是用 C 编写的,而 MFC 是在人们了解之前编写的(实际上是在 c++ 成熟之前)。微软的 API 不是未来的模型,更多的是对过去的警告 ;-)
【解决方案2】:

首先,您使用的是 C++,因此您不需要 typedef 您的结构。你可以这样写。

struct Point3d {
//...
};

typedef 习惯用法是 C 中的规范,但在 C++ 中不是(并且由于您使用 new,因此您显然是在 C++ 中,而不是在 C 中)。

其次,没有区别,因为 typedef 确实是类型别名。

【讨论】:

    【解决方案3】:

    存在差异,但实际上正在发生同样的事情。

     Point3d* _ppoint2 = new Point3d(....);
    

    您正在获取新 Point3d 的地址并将其存储在名为 _ppoint2 的 L 值(左侧)中。你也在做同样的事情

     PPoint3d _ppoint1 = new Point3d(....);
    

    唯一的区别是你如何写 L 值。

    _ppoint2 是一种结构类型,但您使用星号对其进行注释以使其成为指针类型。使用 _ppoint1 您已经“烘焙”了指向结构的指针。

    除了类型之外,它们在功能上是相同的。这种类型的差异意味着您使用它们的方式会有所不同,因为这种方式必须是类型感知的。例如,从 _ppoint1 获取指针值不需要包含星号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 1970-01-01
      相关资源
      最近更新 更多