What Is the Default Value for C++ Class Members

What is the default value for C++ class members

There are no differences between structs and classes in this regard in C++. They all are called just class types.

Members of class types have no default values in general case. In order to for a class member to get a deterministic value it has to be initialized, which can be done by

  • Default constructor of the member itself
  • Constructor initializer list of the enclosing class
  • Explicitly specified initializer for object of the enclosing class (that includes value-initialization and initialization with aggregate initializer).

Additionally, all objects with static storage duration are zero-initialized at the program startup.

Aside from the above cases, class members, once again, have no default values and will initially contain unpredictable garbage values.

Default member values best practice

If a class member is always initialized with the same initial value, then you should make the initializer inline, so as to avoid duplication. If the initial value depends on the constructor, then put it in the constructor initializer list. (And never use assignment in the way you did.)

Example:

class Foo
{
bool done = false; // always start like this
int qty;
Bar * p;

public:
Foo() : qty(0), p(nullptr) { }
Foo(int q, Bar * bp) : qty(q), p(bp) { }
explicit Foo(char const * s) : qty(std::strlen(s)), p(new Bar(s)) { }

// ...
};

In this hypothetical example, the member done is always required to start as false, so it's best to write the initializer inline. The other two members, qty and p, can be initialized differently in each of three different constructors, so they are initialized inside the constructors' initializer lists.

A curiosum: Note that providing an inline initializer prevents your class from having a trivial default constructor.

C++: Default values in class member

You haven't specified the default value for the parameter in the header as such, the compiler is looking for a function of signature void printOut(void) for your statement s.printOut(); but correctly not finding it. What you need is:

class SomeClass
{
public:
SomeClass();
~SomeClass();
void printOut( bool fValue = true ); // Note change in param in definition
}

And in your cpp :

void SomeClass::printOut(bool foobar /*=true*/ )
{
if (foobar) { std::cout << foobar << std::endl; }
}

As a side note, bear in mind you don't have to put the commented out default value for the parameter in the implementation file but it is a good idea for readability.

default value for a class member in c++

your check is what's called an uninitialized variable:

A common assumption made by novice programmers is that all variables are set to a known value, such as zero, when they are declared. While this is true for many languages, it is not true for all of them, and so the potential for error is there. Languages such as C use stack space for variables, and the collection of variables allocated for a subroutine is known as a stack frame. While the computer will set aside the appropriate amount of space for the stack frame, it usually does so simply by adjusting the value of the stack pointer, and does not set the memory itself to any new state (typically out of efficiency concerns). Therefore, whatever contents of that memory at the time will appear as initial values of the variables which occupy those addresses.

This means the value isn't quite random. But more of a 'whatever the value of the thing before was' thing.

Also note that some compilers (such as visual c++) initialise uninitialised memory with magic numbers (In Visual Studio C++, what are the memory allocation representations?) while in debugging mode.

Default initialization of class data members in C++11

when the ctor A::A() is called, how the data member A::i initialized

If no initializer is provided, the rules of default initialization apply. Your constructor does no initialization of A::i so it's left uninitialized; it's value is indeterminate. No doubt about that. Excerpt from the documentation on default initialization:

If T is a class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object.


why only a1.i and aa1[0~2].i are initialized to 0, while others are uninitialized?

The global data memory is initialized to zero i.e. the whole section is zeroed out and so you see global A::is initialized to 0. Note that the constructor would not be doing this. Excerpt from the documentation:

Static initialization

[...]

2) For all other non-local static and thread-local variables, Zero initialization takes place. In practice, variables that are going to be zero-initialized are placed in the .bss segment of the program image, which occupies no space on disk, and is zeroed out by the OS when loading the program.

However, for the vector, the vector itself is in the non-local static memory while its elements are allocated in free store (heap) and hence their members are uninitialized too.

C++11 default constructor behavior with class member default value

Yes.

Unfortunately the wording below is from the standard draft as of today, but the principle is the same in C++11.

[class.default.ctor]/4 A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to create an object of its class type ([intro.object]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer ([class.base.init]) and an empty compound-statement.

[class.base.init]/9 In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then:

  1. if the entity is a non-static data member that has a default member initializer ([class.mem]) and either
    1. the constructor's class is a union ([class.union]), and no other variant member of that union is designated by a mem-initializer-id or
    2. the constructor's class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id, the entity is initialized from its default member initializer as specified in [dcl.init];

[..]



In short, I'm wondering if the default constructor guarantees that default member values will be set.

An example of exactly this follows the passage latterly quoted above.


However, if you were to define A::A() and provide an initialiser for x, it would take precedence over the inline initialiser.

C++ get default value of class member without creating new object

I call this solution workaround

struct ClassWithMember
{
static const int myIntMember_DEFAULT = 10;
int myIntMember = myIntMember_DEFAULT;
}
int myInt = ClassWithMember::myIntMember_DEFAULT;

For pointers it will look more complicated

//.hpp
struct ClassWithMember
{
static AnotherClass* const myMember_DEFAULT; //=X; Assignment not allowed
AnotherClass* myMember = myMember_DEFAULT;
}
//.cpp
AnotherClass* const MyNamespace::ClassWithMember::myMember_DEFAULT = pAnotherInstance;
//usage
auto *my = ClassWithMember::myMember_DEFAULT;

default value in struct and the constructor order

The order initialization happens in is quite rigid, it is always the order the members are declared in.

First of all, all default in-class initializers are applied (in the order that members are declared) unless overruled by the initialization list.

Then the constructors initialization list is used and any members listed there are initialized in the order they are declared. If any of those listed members also have in-class initializers, then those don't happen and the initialization list wins and is used to initialize the members.

Then the constructor body is executed. At this point all members are already initialized, either by in-class initialization or the initializer list. But the constructor body can choose to assign new values to those initialized members.

In any case, for a given member foo it will be initialized by the in class initialization (if any) or by the initialization list (if any) or it will be default initialized. Regardless of the method used to initialize it, that initialization will always happen after another member declared before it and before another member declared after it.

For example:

struct s {
int a = 1;
int b = 42;
int c = 666;
int d;
int e;
s() : e(3), b(123) {
c = 7;
}
};

The above will always initialize a first and since it has an in-class initializer, that will be used. It's value will be 1.

b is initialized second. It has an in-class initializer, but the constructors initialization list overrules that. It will be initialized to the value 123.

Then c is initialized to the value 666.

d is uninitialized / or rather; default initialized, which for a int is the same as uninitialized, but for other types like std::string means initialized to an empty string - it depends on the type whether you have a usable value or not.

Then e is initialized to the value 3. This happens last because it is declared last. The order it is listed in in the initialization list of the constructor is irrelevant.

Then the constructor body is executed and c is assigned the value 7. So it is both initialized and subsequently assigned to - this is usually inefficient.

The object construction is now complete.

Default value C# class

If you are using C# 6 you can do this:

public class Bar {
public string a { get; set; }
public string b { get; set; }
public string c { get; set; } = "foo";
}

Otherwise you can do this:

public class Bar {
public string a { get; set; }
public string b { get; set; }
private string _c = "foo";
public string c
{
get
{
return _c;
}
set
{
_c = value;
}
}
}


Related Topics



Leave a reply



Submit