KcFnMi
KcFnMi

Reputation: 6171

C++ inheritance misunderstanding

Why don't std:cout prints 3?

With the intention of constructing a derived object with a pre-defined m_size the following code was developed. But it seems the idea isn't correctly implemented since std:cout print anything but Data1Size. Could someone please correct me?

untitled.pro    

TARGET = untitled
TEMPLATE = app

QMAKE_CXXFLAGS += -std=c++0x

SOURCES += main.cpp \
    genericdata.cpp

HEADERS  += \
    genericdata.h

main.cpp

#include "genericdata.h"

int main(int argc, char *argv[])
{
    Data1 data;

    return 0;
}

genericdata.h

#ifndef GENERICDATA_H
#define GENERICDATA_H

#include <iostream>

class GenericData
{
    int m_size;

protected:
    const int Data1Size = 3;

public:
    explicit GenericData(int size);
};

class Data1 : public GenericData {
public:
    Data1() : GenericData(Data1Size) {}
};

#endif // GENERICDATA_H

genericdata.cpp

#include "genericdata.h"

GenericData::GenericData(int size) :
    m_size(size)
{
    std::cout << "m_size: " << m_size << std::endl;
}

Upvotes: 0

Views: 52

Answers (2)

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

In-class initializer for non-static member Data1Size

const int Data1Size = 3;

simply means that the compiler will generate an implicit constructor initializer list entry for Data1Size in the constructor of GenericData. So, in reality the constructor of GenericData will look as follows

GenericData::GenericData(int size) :
    m_size(size), Data1Size(3)
{
    std::cout << "m_size: " << m_size << std::endl;
}

It is the constructor of GenericData that sets Data1Size to its initial value of 3.

However, you are accessing Data1Size in the derived class before the constructor of base class GenericData had a chance to do anything. At that moment Data1Size is still uninitialized.

Upvotes: 2

David Schwartz
David Schwartz

Reputation: 182769

You are using Data1Size before it is set here:

Data1() : GenericData(Data1Size) {}

This accesses Data1Size before the GenericData has been constructed. After all, you're preparing the arguments to call the constructor, so it can't have been constructed yet. But Data1Size is a member of GenericData -- you have to already have an instance of that class to access it.

Upvotes: 1

Related Questions