0

I'm building a monitoring IP class, IPmonitoring, that using an SPIFFS class that I wrote, flashLOG. Inside IPmonitoring I have 2 instances of flashLOG (code below).

My sketch have several instances of IPmonitoring for several servicesI wish to monitor. I Wish that connectionLOG and disconnectionLOG have unique and automated names.

For example if I'm monitoring a service called MQTT its connect and disconnect log will be MQTT_discolog.txt and MQTT_conlog.txt. In my code below, filename1 and filename2 are consts.

class IPmonitoring
{
private:
        char *_IP;
        char *_nick;

        flashLOG connectionLOG;
        flashLOG disconnectionLOG;

public:
        IPmonitoring(char *IP, char *nick, char *filename1 = "/conlog.txt", char *filename2 = "/disconlog.txt")
            : connectionLOG(filename1), disconnectionLOG(filename2)
        {
                _IP = IP;
                _nick = nick;
        }

EDIT1 - example how to use class

my goal is that filename1 for example will be MQTTbroker_connlog.txt meaning a combination of _nick and a suffix,

IPmonitoring MQTT_service("192.168.3.200","MQTTbroker");

void setup()
{
MQTT_service.start();
}

void loop()
{
MQTT_service.loop();
}
9
  • Do you mean the variable names in the source code? Any reason why you want this and not use a member in the class flashLOG, initialized by its constructor, to retain its name?
    – Sacha
    Apr 10 at 8:05
  • @Sacha yes, ` filename1` + filename2. I don't understand what is your suggestion, since this is the way flashLOG inits ( with a filename )
    – guyd
    Apr 10 at 8:07
  • Forget about my first comment. In your example, how would the code creating the IPmonitoring instance know the name of the service it will monitor?
    – Sacha
    Apr 10 at 8:23
  • @Sacha - In a case I have more than one instance, using filename1 and filename2 in shown manner will over run each other - it is a not valid way to do so, unless I write each ones name in specific
    – guyd
    Apr 10 at 8:29
  • 1
    you have the filenames as parameters. so construct it with different filenames
    – Juraj
    Apr 10 at 8:32
1

Judging from your example usage, you want the filenames to be built by the IPmonitoring constructor. However, since that class cannot know in advance how much space is needed for the file names, you are left with two choices:

  1. Let those file names be data members: arrays of char of some fixed size. This will impose a limit on the maximum file name length.

  2. Allocate the arrays dynamically at construction time.

Here is a tentative implementation of the second approach:

class IPmonitoring
{
private:
    const char *_IP;
    const char *_nick;
    const char *connectionLOG_filename;
    const char *disconnectionLOG_filename;
    flashLOG connectionLOG;
    flashLOG disconnectionLOG;

    // Return a dynamically allocated string with the concatenation
    // of `a' and `b'.
    const char *str_concat(const char *a, const char *b)
    {
        char *s = new char[strlen(a) + strlen(b) + 1];
        strcpy(s, a);
        strcat(s, b);
        return s;
    }

public:
    IPmonitoring(const char *IP, const char *nick)
        : _IP(IP), _nick(nick),
        connectionLOG_filename(str_concat(nick, "_connlog.txt")),
        disconnectionLOG_filename(str_concat(nick, "_disconnlog.txt")),
        connectionLOG(connectionLOG_filename),
        disconnectionLOG(disconnectionLOG_filename)
    {}

    ~IPmonitoring(){
        delete[] connectionLOG_filename;
        delete[] disconnectionLOG_filename;
    }
};

Note the destructor, which is needed to avoid memory leaks, unless all the instances of the class are statically allocated (which would be good to avoid memory fragmentation). You may want to implement a copy constructor and a copy assignment operator, as per the rule of three.

7
  • Can you please explain : _IP(IP), _nick(nick) I never used such syntax
    – guyd
    Apr 10 at 12:49
  • 1
    @Guy.D: It means “Initialize _IP with the value of IP”. It is functionally equivalent to the assignment you used in the constructor, but it is syntactically an initialization rather than an assignment. It is here intended to make clear that the constructor does nothing more than initialize the data members. Apr 10 at 13:04
  • great! Didn’t know it
    – guyd
    Apr 10 at 13:36
  • Can you please explain/ give an example for static allocate of class ?
    – guyd
    Apr 10 at 14:29
  • 1
    @Guy.D: See your own usage example: the object is a global variable, and global variables are statically allocated. In this case the constructor is called at program startup, before main(), and the destructor is normally never called. Apr 10 at 16:46
1

You have three options for the file names and generally.

  1. constant string a.k.a. string literal
  2. string buffer global or on stack with scope valid while the string is used
  3. dynamically allocated string on heap

with 2) and 3) you can then build a string with C str or sprintf functions

option 3) is alright on MCU if you create these file names only at startup, not if you create them repeatedly as the sketch is running

If you choose option 3) you can build the strings in the constructor of IPmonitoring class, but you can't build the string in the member initialization part of the constructor. You have to add setters to flashLOG class and after building the strings for file names set them to the flashLOG instance with the setters.

1
  • @Guy.D I enhanced the answer
    – Juraj
    Apr 10 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.