0

I'm using a 3rd party library in which a method is declared this way:

void nexLoop(NexTouch *nex_listen_list[]);

In case of a single .cpp file, this is working:

NexButton b0 = NexButton(0, 1, "b0");
NexTouch *nex_listen_list[] = 
{
    &b0,
    NULL
};
...
nexLoop(nex_listen_list);

Full example code can be seen here: https://github.com/itead/ITEADLIB_Arduino_Nextion/blob/master/examples/CompText/CompText.ino

Now I'm incorporating this library in a class which has a separate header and c file, so that:

MyNextion.h

#include "Nextion.h"

class MyNextion {
   public:
       MyNextion();
       void loop();
   private: 
       NexButton *b0;
       NexTouch *nex_listen_list[];
}

MyNextion.cpp

#include "MyNextion.h"

MyNextion::MyNextion() {
    b0 = new NexButton(0, 1, "b0");
    nex_listen_list = new ???
}

MyNextion::loop() {
    nexLoop(nex_listen_list); // ???
}

I was messing around with pointers and address operators but I couldn't find the right combination to a successful compilation.

My question is: what would you put here: nex_listen_list = new ???;

Also, I'm not sure the title well defines my problem. Please correct it if you have a better idea for the title.

Thank you!

5
  • What language is this? Doesn't look like C. Tries to look like C++, but it's failing. Commented Nov 29, 2016 at 20:35
  • Okay you might be right. Actually this is Arduino code which is C/C++. Commented Nov 29, 2016 at 20:36
  • "A new object which is a pointer to an array"? Doesn't make any sense to me. Commented Nov 29, 2016 at 20:37
  • 1
    C/C++ ?? what language is that? Commented Nov 29, 2016 at 20:38
  • Please, feel free to edit the question to make more sense. I'm not a native english speaker. Commented Nov 29, 2016 at 20:38

2 Answers 2

3

You should not declare a member array without a size. Instead you may declare a pointer-to-pointer:

class MyNextion {
   ...
   private: 
       NexButton *b0;
       NexTouch **nex_listen_list;
};

And then the construction is easy:

nex_listen_list = new NexTouch*[10];
nex_listen_list[0] = b0;
....

That is, nex_listen_list is a dynamic array of pointers to NexTouch objects. And do not forget the delete[] when you are finished:

delete[] nex_listen_list;

That said, if the size of the array is constant, a normal array is just fine:

       NexButton *b0;
       NexTouch *nex_listen_list[3];

If not, I'd rather use a std::vector. Something like:

class MyNextion {
   ...
   private: 
       NexButton *b0;
       std::vector<NexTouch*> nex_listen_list;
};

And then no new or delete required:

nex_listen_list.push_back(b0);
nexLoop(nex_listen_list.data());

And going on, you could declare the b0 as a full object, not a pointer:

class MyNextion {
   ...
   private: 
       NexButton b0;
       std::vector<NexTouch*> nex_listen_list;
};
...
nex_listen_list.push_back(&b0); //use the pointer!

No new so no delete and no leaks.

Sign up to request clarification or add additional context in comments.

5 Comments

This is great help already! I managed to get rid of a lot of compiler errors, however I'm facing with others. Please see my updated question. Thank you for your help!
I'd suggest showcasing the use of smart pointers instead of "naked" new / delete, C++11 and all...
@papaiatis: You should really close this question and create a new one. Anyway, you cannot convert a pointer-to-member function into a pointer-to-function, they may look the same but are very different!
@DevSolar: Well, in this case, probably you don't even need the dynamic object at all. But I don't know the used library at all or even if the OP has C++11 available. It is an Arduino after all...
@rodrigo Sure, I'm opening a separate question for that. Thank you again!
2

If nex_listen_list has static size, you should keep it by value:

// Interface
class MyNextion {
public:
   MyNextion() {}
   void loop();
private:
   NexButton b0{0, 1, "b0"};
   NexTouch *nex_listen_list[2] = {&b0, nullptr};
};

// Implementation
void MyNextion::loop() {
   nexLoop(nex_listen_list);
}

If the size is variable, you have two choices. If you don't mind dynamic memory allocation, use std::vector:

// Interface
class MyNextion {
public:
   MyNextion() {}
   void loop();
   void foo();
private:
   NexButton b0{0, 1, "b0"};
   NexButton b1{0, 2, "b1"};
   std::vector<NexTouch *> nex_listen_list{&b0, nullptr};
   void append(NexTouch *t);
};

// Implementation
void MyNextion::append(NexTouch *t) {
   nex_listen_list.back() = t;
   nex_listen_list.push_back(nullptr);
}

void MyNextion::foo() {
   append(&b1);
}

void MyNextion::loop() {
   nexLoop(nex_listen_list.data());
}

Alternatively, you can pre-allocate a fixed-size list and avoid dynamic memory allocation:

lass MyNextion {
public:
   MyNextion() {}
   void loop();
   void foo();
private:
   void append(NexTouch *);
   NexButton b0{0, 1, "b0"};
   NexButton b1{0, 2, "b1"};
   std::array<NexTouch *, 10> nex_listen_list{{&b0, nullptr}};
   std::array<NexTouch *, 10>::iterator it_el =
         std::find(nex_listen_list.begin(), nex_listen_list.end(), nullptr);
};

// Implementation
void MyNextion::append(NexTouch *t) {
   *it_el++ = t;
   *it_el++ = nullptr;
}

void MyNextion::foo() {
   append(&b1);
}

void MyNextion::loop() {
   nexLoop(nex_listen_list.data());
}

You're given a rather powerful C++ compiler. You should leverage it to write code for you. In particular, you should let the compiler generate the code for the constructor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.