Dear StackOverFlowers,
I'm having trouble passing a const char* []
to an object. The scenario is as follows.
I have a class UlamScreen
which contains a const char* []
with several strings. UlamScreen
also contains an object homeScreenMenu
.
class UlamScreen {
const char* homeScreenText[5] = {"EVA dun", "Sabine", "TPU dun", "test Wout",
UlamScreenMenu homeScreenMenu;
};
class UlamScreenMenu {
private:
const char* _menuText[];
public:
UlamScreenMenu(const char*[]);
void drawMenu();
};
I want to pass the const char* []
to UlamScreenMenu
so I can use it in a member function called void drawMenu
, like this:
void UlamScreenMenu::drawMenu() {
for (int i = 0; i < menuItems; i++) {
tft.println(_menuText[i]);
}
}
I passed it to UlamScreenMenu's
constructor like this:
UlamScreen::UlamScreen() : homeScreenMenu(homeScreenText) {
}
UlamScreenMenu::UlamScreenMenu(const char* menuText[], int length) {
for(int i = 0; i < length; i++) {
_menuText[i] = menuText[i];
}
}
I thought this would work, but for some reason, it does not. tft.println(_menuText[i]);
used with void drawMenu
does not send anything to my tft screen. When I use tft.println(_menuText[i]);
from within the UlamScreen class it works perfectly.
Just to be clear, I can use the tft
object within the UlamScreenMenu
class because other functions like tft.drawRect()
are working correctly.
What is wrong with this way of passing the const char* []
? Thanks in advance.
In C++, you can't declare a member variable of type const char* x[]
, since this would denote a flexible array member. Flexible array members are a C-feature allowing the last member of a struct to be an array of varying size (cf., for example, Arrays of unknown size / flexible array members ). Having parameters of type const char* x[]
in functions, however, is supported and has basically the same meaning as const char** x
.
If you stick to a member of type const char**
, then you'll have to handle memory management in that class. This means: take care of allocating, deallocating, copying, moving, copy-assigning, and move-assigning objets of that class (cf, for example, the rule of 0/3/5 ).
If - as suggested in the comments - you use standard library collections, eg std::vector
, these classes will do all this stuff in a reliable manner for you. See the following example illustrating the difference between both:
Note that the C++-version probably would not even take a const char*[]
-parameter but directly a const std::vector<const char*> &x
-parameter. But I kept the const char*[]
-parameter in the constructor to provide the same interface in both variants:
// Variant 1: "old" C-style:
class Menu {
public:
Menu(const char* x[], int length) {
m_x = new const char*[length];
m_length = length;
for (int i=0; i<length; i++) {
m_x[i] = x[i];
}
}
~Menu() {
delete[] m_x;
}
// TODO: implement copy- and move constructors + copy- and move assignments
// ...
void print() {
for (int i=0; i<m_length; i++) {
std::cout << m_x[i] << std::endl;
}
}
private:
const char** m_x = nullptr;
int m_length;
};
#include <vector>
// Variant 2: a C++- way:
class Menu2 {
public:
Menu2(const char* x[], int length) {
m_x.assign(x, x+length);
}
void print() {
for (auto s : m_x) {
std::cout << s << std::endl;
}
}
// Menu2 does not manage memory on its own, hence:
// No special copy/move - constructors/assignments to be implemented.
// No special destructor necessary
private:
std::vector<const char*> m_x;
};
int main() {
const char* x1[3] = {"one","two","three" };
const char* x2[2] = {"eins","zwei" };
// Variant 1
Menu m1(x1, 3);
m1.print();
// Variant 2
Menu2 m2(x2, 2);
m2.print();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.