Initialize members of a structure, accessed via pointer, in the constructor of a C++ class

Asked

Viewed 65 times

0

Imagine the class DateTime as follows:

datetime.hpp:

#ifndef DATETIME_HPP
#define DATETIME_HPP

#include <ctime>

class DateTime {
    public:
        DateTime();
        DateTime(int, int, int, int, int); 

    private:
        std::tm *date;
};
#endif // DATETIME_HPP

datetime.cpp:

#include "datetime.hpp"

DateTime::DateTime() : date(new std::tm)
{
    //date = new std::tm;
    date->tm_sec    = 0;
    date->tm_min    = 0;
    date->tm_hour   = 0;
    date->tm_mday   = 0;
    date->tm_mon    = 0;
    date->tm_year   = 0;
    date->tm_wday   = 0;
    date->tm_yday   = 0;
    date->tm_isdst  = 0;
    date->tm_gmtoff = 0;
    date->tm_zone   = 0;
}

DateTime::DateTime(int _D, int _M, int _Y, int _h, int _m) : date(new std::tm)
{
    date->tm_sec    = 0;
    date->tm_min    = _m;
    date->tm_hour   = _h;
    date->tm_mday   = _D;
    date->tm_mon    = _M;
    date->tm_year   = _Y-1900;
    date->tm_wday   = 0;
    date->tm_yday   = 0;
    date->tm_isdst  = 0;
    date->tm_gmtoff = 0;
    date->tm_zone   = 0;
}

The above code works as long as I store memory in the constructor list and define the structure fields in the constructor body. I’d like to do everything on the constructor startup list, but I’m really having a hard time figuring it out.

It would be something like:

: date(new std::tm), date{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

and:

: date(new std::tm), date{0, _m, _h, _D, _M, _Y-1900, 0, 0, 0, 0, 0}
  • 1

    Do not construct a hybrid answer of English and Portuguese because it ends up complicating and making the question more confusing to both Portuguese and English speakers. This being the Portuguese community of Stackoverflow the correct is to leave the question only with the Portuguese text. If you want you can also ask the same question in the English version of Stackoverflow with the texts you have in English.

  • Man, I think I understand your question now, but I believe that what you wish to do is not possible. The initialization list is only for initialization of object attributes, and does not serve for "attribute attributes".

  • 3

    @Leonardoalvesmachado, it is possible, yes, making the initialization aggregated by the operator new, thus: date(new std::tm{0, _m, _h, _D, _M, _Y-1900, 0, 0, 0, 0, 0}).

  • @Márioferoldi Puts this solution as an answer

  • @Márioferoldi good to know! I had never used this way. Thanks... Put as answer there :)

1 answer

1

If date is a private member of its class and its life cycle always accompanies the class instance DateTime, I don’t see the need to use dynamic allocation to boot it.

Note that the struct tm has a dozen members, initializing it in the boot list of the constructor can degrade the readability of your code, making it difficult to understand and maintain.

I suggest something more readable and less complex, without using the list of initializations of the class builder, see:

datetime.hpp:

#ifndef DATETIME_HPP
#define DATETIME_HPP

#include <ctime>

class DateTime {
    public:
        DateTime();
        DateTime( int day, int month, int year, int hours, int minutes ); 

    private:
        std::tm m_date;
};
#endif 

datetime.cpp:

#include <cstring>
#include <ctime>

#include "datetime.hpp"

DateTime::DateTime()
{
    std::memset( &m_date, 0, sizeof(m_date) );
}

DateTime::DateTime( int day, int month, int year, int hours, int minutes )
{
    std::memset( &m_date, 0, sizeof(m_date) );

    m_date.tm_min    = minutes;
    m_date.tm_hour   = hours;
    m_date.tm_mday   = day;
    m_date.tm_mon    = month - 1;
    m_date.tm_year   = year - 1900;
}
  • I understand that it would increase the complexity of readability. Still, if possible, I would like to know how to proceed to do so. This code is for reasons of study. Thus, I think it is valid for someone to answer what was placed as doubt, even for others to take away the learning. In many places, if you search, you only see very trivial examples of the use of startup lists. No one gives a heavier example, like this, where you have a pointer to a structure, inside a pointer to a class instance. Therefore, I think it is valid to remain open to the question.

  • It is also worth noting that it is more efficient to use a boot list than to clog up the body of the constructor of things that might be on the list, and still provoking instantiations that could be avoided.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.