4

I got what POD means, and I know that when I declare a structure in C++ as

struct f {};

there's a default constructor, a default copy constructor, a default destructor, etc.. (if I got this correctly)

My question is: how can I declare a POD structure with just plain data (like 4 int values) without implicit constructors/destructors/etc.. getting in the way?

Did I miss something?

arekolek
  • 9,128
  • 3
  • 58
  • 79
Johnny Pauling
  • 12,701
  • 18
  • 65
  • 108
  • 1
    What do you mean with "without implicit constructors/destructors/etc. getting in the way"? If you don't want them, you can provide alternatives (for the copy constructor and copy assignment) and suitable other constructors. – Dietmar Kühl Oct 19 '12 at 17:41
  • 3
    "getting in the way"? What does that mean? – AnT stands with Russia Oct 19 '12 at 17:43
  • I mean getting a plain POD structure without generated member functions – Johnny Pauling Oct 19 '12 at 17:44
  • 2
    @JohnnyPauling: the purpose of the generated member functions is to make the class behave the same as a `struct` does in C. Without them, you wouldn't be able to create/destroy/copy your POD struct. – Steve Jessop Oct 19 '12 at 17:45
  • @Johnny Pauling: That's still not sufficiently clear. What do you think changes because of those extra member functions? How do they specifically "get in the way" in your case? – AnT stands with Russia Oct 19 '12 at 17:45
  • @AndreyT It's a mere theoretical question, I was thinking that these function could spoil a "memory mapping", but this doesn't sound quite right – Johnny Pauling Oct 19 '12 at 17:52
  • 1
    @AndreyT I think he means "take away the property that f is POD". He is just missing the "user-defined" part. – pmr Oct 19 '12 at 17:52

4 Answers4

7

Every object type has a constructor—else how would you construct it?—and a destructor—else how would it be destroyed? They don’t “get in the way” of anything, because the default implementations are no-ops in the case of POD-only fields, just as if you had said:

struct f {
    f() {}
    ~f() {}
    int a, b, c, d;
};

However, if you write an empty constructor, the type becomes non-POD. C++11 solves this with defaulting:

f() = default;
~f() = default;

The situation is slightly different with copy constructors, where the implicitly generated one is just a convenience that does “the right thing” for POD types:

f(const f& other) : a(other.a), b(other.b), c(other.c), d(other.d) {}

There is no reason to rewrite this yourself. If you want to make a type noncopyable, you can mark the copy constructor as deleted with f(const f&) = delete; or declare it private.

It’s also important to note that member functions are not stored on the object as member variables are. You can think of a class or struct as simultaneously two things:

  1. A description of a data layout

  2. A namespace containing functions and types for manipulating that data

The C++ model of object-oriented programming simply couples these two things in one place.

Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
  • 4
    This is not technically correct. The default implementations are not no-ops - they initialize non-POD members (not applicable in this case). Also, writing empty constructors is in no way equivalent to not writing them. By having a constructor (even empty), the type is no longer a POD. – Luchian Grigore Oct 19 '12 at 18:49
  • "Every object type has a constructor". That's actually not true. Objects of `int` type (or any other scalar type) have no constructors. Every *class* type has a constructor - that would be true. – AnT stands with Russia Oct 19 '12 at 18:55
  • @LuchianGrigore: Right. I wrote “no-op” because it’s true in the OP’s context—POD-only fields, and I didn’t mean to imply that an empty constructor is the same as a defaulted one. – Jon Purdy Oct 19 '12 at 20:49
  • @AndreyT `int` and other scalar types don't have a constructor because they're not `class`es, but only types. – codeling Aug 23 '13 at 12:56
  • @nyarlathotep: Er... As I said above, `int` does not have a constructor because non-class types have no constructors. Now you are saying the same thing to me. So, what point are you trying to make? – AnT stands with Russia Aug 23 '13 at 18:02
  • you are saying, and I quote "*Objects* of `int` type [...]". I just wanted to object to the usage of the word *Object* in this context. I know what you mean by it - as you stated now that non-class types don't have a constructor - but the usage of the word *Object* in this context could confuse people into thinking that an `int` is treated the same as an object in C++... sorry if I seem nitpicky, but to me that sentence just sounded a bit confusing on first read - maybe I'm the only one digging through old comments anyway ;) – codeling Aug 23 '13 at 21:05
  • @AnT int is not an object. Objects, in C++ parlance, are instances of classes. int is not an instance of a class, so it is not an object. – srm Mar 29 '17 at 19:56
  • 3
    @srm: That's completely false. The term *object* plays a very important role in the conceptual world of C and C++ languages. And no, it has nothing to do with "instances of classes". Every data entity that occupies storage is an object. Every `int` variable is an object of type `int`. – AnT stands with Russia Mar 29 '17 at 20:29
  • @AnT I have never heard anyone use that broad a definition of object. C code does not have objects. C++ does. In C#, an int is not an instance of object -- it has to be boxed to be handled as an object. Where have you seen the usage that you describe? – srm Mar 29 '17 at 20:56
  • 2
    @srm: Um... C and C++ are two well standardized languages with very formal and strict terminology. Open C standard or C++ standard and you will immediately find exactly the usage I describe. Here's a quote from C standard: "**3.15 object**: region of data storage in the execution environment, the contents of which can represent values". And you are telling me that C "does not have objects"? Again, in C and C++ the concept of "object" is one of the most important ones. And no, it has nothing to do with classes. – AnT stands with Russia Mar 29 '17 at 21:02
  • I have never ever heard that usage before, but I acknowledge your citation. I don't think it is common parlance, but you are correct, it appears to be technically correct. @AnT – srm Mar 29 '17 at 21:05
  • @AnT So what makes C++ object oriented if not the classes and their instantiated objects? – srm Mar 29 '17 at 21:07
  • 1
    The usage of the term "object" that you are reffing to is specific to OO terminology. But in C and C++ terminology it has a different meaning. In most cases it is clear from context what this term is intended to mean. Since this question is tagged [C++] and is not restricted to OO, it is natural to assume that the term "object" is used in its C++ meaning and not restricted to its OO meaning. – AnT stands with Russia Mar 29 '17 at 21:07
  • 1
    And I don't see how the more technical meaning of the term "object" in formal C++ parlance would interferere with C++ being "object oriented". It is just a matter of terminology. You can still use the term "object" in its purely OO meaning, as long as you are sure that everyone properly understands what you mean. But if out of the blue you will suddenly make such contextless asserions as "int variables are not objects", people are likely to disagree. – AnT stands with Russia Mar 29 '17 at 21:09
5

how can I declare a POD structure with just plain data (like 4 int values) without implicit constructors/destructors/etc.. getting in the way?

Like this:

struct f {
  int i1, i2, i3, i4;
};

Compiler-generated constructors don't get in the way of it being a POD.

9 Classes [class]

10) A POD struct109 is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). Similarly, a POD union is a union that is both a trivial class and a standard layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). A POD class is a class that is either a POD struct or a POD union.

So, it has to be

a) A trivial class and
b) A standard-layout class.

which are described below:

7) A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with
non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member.

and

6) [...] A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable

Detailed in:

12.1 Constructors [class.ctor]

5) [...]A default constructor is trivial if it is not user-provided and if:
— its class has no virtual functions (10.3) and no virtual base classes (10.1), and
— no non-static data member of its class has a brace-or-equal-initializer, and
— all the direct base classes of its class have trivial default constructors, and
— for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.

As all conditions above apply, the class is a POD.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
2

Firstly, all these implicit member function exist only conceptually. The don't really affect anything until you actually attempt to use them. This means that they should not be "getting in the way" if you don't want them to.

Secondly, non-virtual member functions (regardless of whether they are explicitly declared or not) have no effect on data layout of the class. I.e. they are not "getting in the way" in that regard (if that's what you meant).

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

Yes, the definition of POD explicitly excludes the implicitly generated special member functions. It gets trickier if you specify one of them that does exactly the same as the default generated one: Your type is no longer POD. In C++11 this problem is solved with the default keyword.

With all this, the definition of a POD is (usually) just the same as you would have in C code:

struct X { int a, b, c, d; };
pmr
  • 58,701
  • 10
  • 113
  • 156