Can't C++ Pod Type Have Any Constructor

Can't C++ POD type have any constructor?

POD means Plain Old Data type which by definition cannot have user-defined constructor.

POD is actually an aggregate type (see the next quotation). So what is aggregate? The C++ Standard says in section §8.5.1/1,

An aggregate is an array or a class
(clause 9) with no user-declared
constructors
(12.1), no private or
protected nonstatic data members
(clause 11), no base classes (clause
10), and no virtual functions (10.3).

And section §9/4 from the C++ Standard says,

[....] A POD-struct is an aggregate class that has no non-static data
members of type non-POD-struct,
non-POD-union (or array of such types)
or reference, and has no user-defined
copy assignment operator
and no
user-defined destructor
. Similarly, a
POD-union is an aggregate union that
has no non-static data members of type
non-POD-struct, non-POD-union (or
array of such types) or reference, and
has no user-defined copy assignment
operator
and no user-defined
destructor
. A POD class is a class
that is either a POD-struct or a
POD-union.

From this, its also clear that POD class/struct/union though cannot have user-defined assignment operator and user-defined destructor also.


There are however other types of POD. The section §3.9/10 says,

Arithmetic types (3.9.1),
enumeration types, pointer types, and
pointer to member types (3.9.2), and
cv-qualified versions of these types
(3.9.3) are collectively called scalar
types. Scalar types, POD-struct types,
POD-union types (clause 9), arrays of
such types and cv-qualified versions
of these types (3.9.3) are
collectively called POD types
.

Read this FAQ : What is a "POD type"?

Default constructors and POD

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.

What are POD types in C++?

POD stands for Plain Old Data - that is, a class (whether defined with the keyword struct or the keyword class) without constructors, destructors and virtual members functions. Wikipedia's article on POD goes into a bit more detail and defines it as:

A Plain Old Data Structure in C++ is an aggregate class that contains only PODS as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type.

Greater detail can be found in this answer for C++98/03. C++11 changed the rules surrounding POD, relaxing them greatly, thus necessitating a follow-up answer here.

Do primitive types have also constructors in C++?

What Bjarne means is that you can write int(56) or even int() to construct an integer. What the links means is that a struct/class is only a POD if it does not have a constructor declared. So Bjarne talks about primitive non-struct types and the link talks about structs/classes so the two sources can coexist without contradicting each other.

Here is part of the definition from the link:

a POD type's non-static data members must be public and can be of any of these types

Of course, this can only hold for structs. An int has no "data members". So although the link never mentions it directly, it only refers to structs and classes.

How to understand this POD rule

The reason is simple. Once you define a constructor (any
constructor), the language assumes that the class needs some
sort of initialization; that just copying the bits in its image
won't be sufficient to create a new instance. And one of the
important characteristics of PODs is that they can be memcpy'ed.

In sum, the compiler does not look at the contents of a class
to determine whether it is POD or not (except to see if any of
the members are PODS). It looks at whether you've defined anything
special which might affect the initialization, assignment or
destruction of those members.

C++ guarantee and name for POD-like data, memcpy capable

In C++0x, the concept of PODness is broken out into several individually useful categories:

A trivially copyable class is a class that (draft 3242, section [class]):

  • has no non-trivial copy constructors (12.8),
  • has no non-trivial move constructors (12.8),
  • has no non-trivial copy assignment operators (13.5.3, 12.8),
  • has no non-trivial move assignment operators (13.5.3, 12.8), and
  • has a trivial destructor (12.4).

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

[ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base
classes. — end note ]

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.

The requirements for trivial constructors, assignment operators, and destructor are scattered throughout section 12 "Special Member Functions" [special].



Related Topics



Leave a reply



Submit