1

I am writing a struct _Point3d and typedefed it to Point3d and provided a pointer declaration PPoint3d next to Point3d (Please see code). There is a constructor which initializes members of the struct. I have twofold queries here.

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

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

    }

}Point3d, *PPoint3d;

One: What does this convention of providing pointer after struct name (typedef) really means? provided we can create the pointer of Point3d like this

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

Two: Is there any difference in creating instances of Point3d in these two different ways.

PPoint3d _ppoint1 = new Point3d(0.0, 1.0, 0.0);
Point3d* _ppoint2 = new Point3d(1.0, 0.0, 0.0);
Garf365
  • 3,619
  • 5
  • 29
  • 41
A.B.
  • 1,554
  • 1
  • 14
  • 21
  • `Point3d` is a `struct _Point3d` and `PPoint3d` is a `struct _Point3d*` or in other word a pointer to `struct _Point3d` or a pointer to `Point3d`. Second question, no it's the same thing. – Jabberwocky Mar 15 '16 at 13:01
  • 1
    1) The typedefing of the pointer here is in my opinion the work of cranks that don't like the language syntax. 2) There is no difference. 3) Names in global namespace beginning with an underscore are reserved. – StoryTeller - Unslander Monica Mar 15 '16 at 13:02
  • 5
    Why is this tagged C when you are using `new`? If this is just for C++ then the declaration does not follow the C++ convention for declaring and using classes. – NathanOliver Mar 15 '16 at 13:03
  • 1
    actually I dont see the point of using a typedef here at all. imho it is much simpler and more clear to write `struct Point3d { float x,y,z;}` there is no need for a typedef – 463035818_is_not_an_ai Mar 15 '16 at 13:03
  • 1
    You write a lot of C code before, right ? So, forget everything and learn C++ like a new language – Garf365 Mar 15 '16 at 13:04
  • 1
    Related: [Difference between 'struct' and 'typedef struct' in C++?](http://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c) – Fabio says Reinstate Monica Mar 15 '16 at 13:10
  • That funky typedef is a Microsoft-ism; it's their convention for defining C types for the Windows API. It's not needed in C++, and it mostly just looks silly. – Pete Becker Mar 15 '16 at 14:56
  • Names that begin with an underscore followed by a capital letter (`_Point3d`) and names that contain two consecutive underscores are reserved to the implementation. Don't use them. – Pete Becker Mar 15 '16 at 14:57

3 Answers3

4

I am writing a struct _Point3d and typedefed it to Point3d and provided a pointer declaration *PPoint3d next to Point3d

Stop right there, Kiddo. This is 2016, not 1997. No need to follow arcane microsoft practice any more.

Do this instead:

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>;

Raw pointers are to be used in low-level implementations. When used as part of an interface they make your code susceptible to being silently hijacked by your user's unintended and un-noticed mistakes.

For this reason they are evil when used as part of an interface. So evil that it is evil to even hint to users of your class that they should use them.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • 5
    Can we get off the train of "raw pointers are *so* evil". There is nothing wrong with non-owning raw pointers. – StoryTeller - Unslander Monica Mar 15 '16 at 13:03
  • @StoryTeller The reason for the existence of `std::experimental:: observer_ptr` is precisely because raw pointers are evil, especially when used as observers, simply because a user can hijack them by mistake. – Richard Hodges Mar 15 '16 at 13:06
  • `observer_ptr` will not prevent undisciplined users from doing something bad. It's just ridiculous to assume the language feature is evil in itself. – StoryTeller - Unslander Monica Mar 15 '16 at 13:08
  • 2
    @StoryTeller you're right. The language feature itself is necessary and 'not evil', but the use of it as part of an interface certainly is. I'll update the answer. – Richard Hodges Mar 15 '16 at 13:09
  • everything is evil when you misuse them. The appearance of newer paradigms doesn't make older ones evil – pcodex Mar 15 '16 at 13:10
  • Agree with @Richard Hodges, and consider the scenario of legacy application written in C (no C++), could I avoid raw pointers then? – A.B. Mar 15 '16 at 13:11
  • 2
    @A.B. I assume you mean when using the C features from the C++ programs? I would encourage you to wrap the C pointers in C++ smart pointers at the earliest opportunity. The custom deleter of the smart pointers makes this possible in every scenario. – Richard Hodges Mar 15 '16 at 13:13
  • Roger That! and what is the purpose of *PPoint3d in the line "} Point3d, *PPoint3d;" I have seen this conventions alot in Win32 API. – A.B. Mar 15 '16 at 13:18
  • 1
    @A.B. The win32 API was written in C a long time ago, and the MFC was written before people knew better (and indeed before c++ was mature). Microsoft's APIs are not a model of the future, more a warning about the past ;-) – Richard Hodges Mar 15 '16 at 13:21
3

First, you are in C++, so you don't need to typedef your structs. You can write this.

struct Point3d {
//...
};

The typedef idiom is the norm in C, but not in C++ (and since you use new you clearly are in C++, not in C).

Secondly, there is no difference, as a typedef really is a type alias.

Louen
  • 3,617
  • 1
  • 29
  • 49
1

There are differences, but effectively the same thing is happening.

In

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

You are taking the address of the new Point3d and storing it in the L-value (left hand side) called _ppoint2. You are doing the same with

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

The only difference is how you are writing the L-value.

_ppoint2 is a struct type, but you are annotating it with an asterisk to make it a pointer type. With _ppoint1 you have "baked in" the pointer to the struct.

Functionally they are identical except in type. This difference in type means that the manner in which you use them will differ, because that manner must be type-aware. For example, one does not need to include the asterisk to get the pointer value from _ppoint1.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138