user48730: I have a class with 12 instances of a button, to create a keypad( meaning that this is the only case I use 12 instances). But this class can be just a button array of any other number between 1-12. I'm looking for a way to minimize class overhead of 12 instances, when I most of the time use much less.
'.h' file:
class buttonArrayTFT
{
public:
  buttonArrayTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft);
  void create_array(uint8_t R, uint8_t C, char *but_txt[]);
  uint8_t checkPress(TS_Point &p);

public:
  
protected:
  ButtonTFT _button0;
  ButtonTFT *_buttons[12] = {&_button0, &_button1, &_button2, &_button3,
                             &_button4, &_button5, &_button6, &_button7,
                             &_button8, &_button9, &_button10, &_button11};
private:
  ButtonTFT _button1;
  ButtonTFT _button2;
  ButtonTFT _button3;
  ButtonTFT _button4;
  ButtonTFT _button5;
  ButtonTFT _button6;
  ButtonTFT _button7;
  ButtonTFT _button8;
  ButtonTFT _button9;
  ButtonTFT _button10;
  ButtonTFT _button11;
  
private:
  uint8_t _num_items = 0;
};


user37622: There are more options to solve your question.

To use a template as recommended in the other answers is a fancy option, but if you use a template multiple times, it creates a real class for every template value and you will see it on used flash size.

The best option in my opinion is to provide the array to the class over a constructor. Create a global array of buttons and hand it over to buttonArrayTFT object over a constructor.
const uint8_t BUTTON_COUNT = 12;
ButtonTFT buttons[BUTTON_COUNT];
ButtonArrayTFT buttonArrayTFT(buttons, BUTTON_COUNT);

The ButtonArrayTFT class (simplified) would be like:
class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(ButtonTFT *_buttons, uint8_t _count) {
    buttons = _buttons;
    count = _count;
  }


Other option is to use dynamic allocation on heap. If you would create a ButtonArrayTFT object only once at start and never delete it it would not cause heap fragmentation.
class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(uint8_t _count) {
    count = _count;
    buttons = new ButtonTFT[count];
  }


user4143: You can use a template class to provide compile time parameters to your class to tune it. This is most often used in the context of providing a type for the class to operate on. However it's not limited to that. It's also often used to provide a storage size or other similar constant to the class.
They kind of work like preprocessor macros. You specify a token in the class and then give that token a value when you instantiate an object. That token can then be used all over the place in your class.
In your case you can provide the number of elements in your array of buttons as a template variable, for example (note: untested):
template <int N> class buttonArrayTFT {
    protected:
        ButtonTFT _buttons[N];
    public:
        void doSomething();
};

template <int N> void buttonArrayTFT::doSomething() {
    for (int i = 0; i < N; i++) {
        _buttons[i].doSomethingOnAButton();
    }
}

Of course you have to treat your objects a little differently since you can't make an array of pointers to predefined objects any more. Instead just a simple array of objects should be enough.
You then instantiate your class passing the number of elements you want:
// Array of 12 buttons
buttonArrayTFT<12> myButtons;
// and do something
myButtons.doSomething();


user10003: As pointed out in a comment on your original question, a template is likely the best solution.
Templates allow you to write highly flexible code. I won't explain why; that's something that goes a little beyond the actual question. However, the following will show that you can create a template that means you can create a buttonArrayTFT class with N number of buttonTFT elements, so long as N is known at compile time. The link given as  a comment talks describes various aspects of templates but does not necessarily explain how to string it all together.
From the section Non-type parameters for templates, you will see that you can specify an integer as a parameter for creating N elements of an array member variable.
But what about the type parameter, T? You can simply omit it. You don't actually have to create a template for a type.
In your .h file:
template <uint8_t ARRAY_SIZE>
class buttonArrayTFT
{
public:
// One thing to remember about templates: you have to pack the definition
// into the header file with the declaration to avoid all manner of headaches.

    buttonArrayTFT(XPT2046_Touchscreen &_ts = ts, Adafruit_ILI9341 &_tft = tft)
    {
    // Perhaps this is a good opportunity to check that the specified
    // size of the array is sensible, i.e. not zero and no more than 12.
        if ((ARRAY_SIZE == 0) || (ARRAY_SIZE > 12))
        {
            // decide how you want to handle this problem
        }
            // Add the rest of your constructor here
    }

    void create_array(uint8_t R, uint8_t C, char *but_txt[]);
    uint8_t checkPress(TS_Point &p);
        
    // This little piece of magic allows you to access buttonTFT 'x' of the
    // private _buttonArray as if a buttonArrayTFT class was an array
    buttonTFT &operator[](uint8_t index)
    {
    // Check that 'index' is a valid element in the array
        if (index > _num_items)
        {
            // decide how you want to handle this problem
        }
        return _buttonArray[index];
    }
private: 
    buttonTFT _buttonArray [ARRAY_SIZE];
    // I recommend making this constant
    const uint8_t _num_items = ARRAY_SIZE;
};

I shall leave it up to you to sort out your privates, publics and protecteds, and I have left out ButtonTFT _button0; to keep you on your toes.
You'll also notice that the array is private, as before, but there is now no array-of-pointers-to-buttons. This is because there is no need; the magic buttonTFT &operator[](int index) allows you to access array elements directly.
In your .ino file, or as appropriate, you use the following code to create and then wield the class:
buttonArrayTFT<4> myFourButtonArray(/* constructor arguments as required*/);
buttonArrayTFT<12> myTwelveButtonArray(/* constructor arguments as required*/);

This gives you two instances of the class, with the respective number of buttonTFT elements! You can now access specific buttons using the following code:
myFourButtonArray[0];    // Returns a reference to the first buttonTFT
myTwelveButtonArray[10]; // Returns a reference to the eleventh buttonTFT
myFourButtonArray[n]     // Returns a reference to the 'n+1'th buttonTFT

On the assumption that the buttonTFT class has some kind of 'read' function that returns a TRUE or FALSE for the status of the button, you can write:
if (myFourButtonArray[0].read())
{
    // executed if the button is ON
}
else
{
    // executed if the button is OFF
}

A NOTE ON CONST-NESS:
The overloading of operator[], while wonderfully magic, is open to abuse. However, this is no different from your original code. The array of buttonTFT elements is private but there is public access to all the buttons almost as if the array was not private. In the case of your original code, one could write:
myButtonArray._buttons[0] = myButtonArray._buttons[1];

Now _buttons[0] points to the same buttonTFT as _buttons[1].
Ouch. Now myButtonArray._buttons[0]->read() is literally the same thing as myButtonArray._buttons[1]->read().
That said, my code does not make it a great deal better; the equivalent code:
myFourButtonArray[0] = myFourButtonArray[1];

Simply copies the right hand side over to the left hand side. You still have two distinct buttonTFT instances, with probably no memory leaks, but I am guessing that buttonTFT class may contain a reference to an Input pin, so the _button[0] pin will now be whatever _button[1] pin is because the member variable that stores the pin reference will be overwritten.
To solve this weakness, simply add the const qualifier to the beginning of the operator[] overload:
const buttonTFT &operator[](uint8_t index)
{ // };

Now the buttonTFT element cannot be altered. This of course brings in a new headache that all functions that rely on myArray[n] also need to be constant. It is up to you to determine how constant correctness should be interpreted and whether it is worth the hassle.

48730: <p>I have a class with 12 instances of a button, to create a keypad( meaning that this is the only case I use 12 instances). But this class can be just a button array of any other number between 1-12. I'm looking for a way to minimize class overhead of 12 instances, when I most of the time use much less.</p>
<p>'.h' file:</p>
<pre><code>class buttonArrayTFT
{
public:
  buttonArrayTFT(XPT2046_Touchscreen &amp;_ts = ts, Adafruit_ILI9341 &amp;_tft = tft);
  void create_array(uint8_t R, uint8_t C, char *but_txt[]);
  uint8_t checkPress(TS_Point &amp;p);

public:
  
protected:
  ButtonTFT _button0;
  ButtonTFT *_buttons[12] = {&amp;_button0, &amp;_button1, &amp;_button2, &amp;_button3,
                             &amp;_button4, &amp;_button5, &amp;_button6, &amp;_button7,
                             &amp;_button8, &amp;_button9, &amp;_button10, &amp;_button11};
private:
  ButtonTFT _button1;
  ButtonTFT _button2;
  ButtonTFT _button3;
  ButtonTFT _button4;
  ButtonTFT _button5;
  ButtonTFT _button6;
  ButtonTFT _button7;
  ButtonTFT _button8;
  ButtonTFT _button9;
  ButtonTFT _button10;
  ButtonTFT _button11;
  
private:
  uint8_t _num_items = 0;
};
</code></pre>
 37622: <p>There are more options to solve your question.</p>
<hr />
<p>To use a template as recommended in the other answers is a fancy option, but if you use a template multiple times, it creates a real class for every template value and you will see it on used flash size.</p>
<hr />
<p>The best option in my opinion is to provide the array to the class over a constructor. Create a global array of buttons and hand it over to buttonArrayTFT object over a constructor.</p>
<pre><code>const uint8_t BUTTON_COUNT = 12;
ButtonTFT buttons[BUTTON_COUNT];
ButtonArrayTFT buttonArrayTFT(buttons, BUTTON_COUNT);
</code></pre>
<p>The ButtonArrayTFT class (simplified) would be like:</p>
<pre><code>class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(ButtonTFT *_buttons, uint8_t _count) {
    buttons = _buttons;
    count = _count;
  }
</code></pre>
<hr />
<p>Other option is to use dynamic allocation on heap. If you would create a ButtonArrayTFT object only once at start and never delete it it would not cause heap fragmentation.</p>
<pre><code>class ButtonArrayTFT {
private:
  ButtonTFT *buttons;
  uint8_t count;
public:
  ButtonArrayTFT(uint8_t _count) {
    count = _count;
    buttons = new ButtonTFT[count];
  }
</code></pre>
 4143: <p>You can use a <em>template</em> class to provide compile time parameters to your class to tune it. This is most often used in the context of providing a <em>type</em> for the class to operate on. However it's not limited to that. It's also often used to provide a storage size or other similar constant to the class.</p>
<p>They kind of work like preprocessor macros. You specify a token in the class and then give that token a value when you instantiate an object. That token can then be used all over the place in your class.</p>
<p>In your case you can provide the number of elements in your array of buttons as a template variable, for example (note: untested):</p>
<pre class="lang-cpp prettyprint-override"><code>template &lt;int N&gt; class buttonArrayTFT {
    protected:
        ButtonTFT _buttons[N];
    public:
        void doSomething();
};

template &lt;int N&gt; void buttonArrayTFT::doSomething() {
    for (int i = 0; i &lt; N; i++) {
        _buttons[i].doSomethingOnAButton();
    }
}
</code></pre>
<p>Of course you have to treat your objects a little differently since you can't make an array of pointers to predefined objects any more. Instead just a simple array of objects should be enough.</p>
<p>You then instantiate your class passing the number of elements you want:</p>
<pre class="lang-cpp prettyprint-override"><code>// Array of 12 buttons
buttonArrayTFT&lt;12&gt; myButtons;
// and do something
myButtons.doSomething();
</code></pre>
 10003: <p>As pointed out in a comment on your original question, a <strong>template</strong> is likely the best solution.</p>
<p>Templates allow you to write highly flexible code. I won't explain why; that's something that goes a little beyond the actual question. However, the following will show that you can create a template that means you can create a <code>buttonArrayTFT</code> class with <em>N</em> number of <code>buttonTFT</code> elements, so long as <em>N</em> is known at compile time. The <a href="http://www.cplusplus.com/doc/oldtutorial/templates/" rel="nofollow noreferrer">link given as  a comment</a> talks describes various aspects of templates but does not necessarily explain how to string it all together.</p>
<p>From the section <strong>Non-type parameters for templates</strong>, you will see that you can specify an integer as a parameter for creating <em>N</em> elements of an array member variable.</p>
<p>But what about the <em>type parameter, T</em>? You can simply omit it. You don't actually have to create a template for a <em>type</em>.</p>
<p>In your <em>.h</em> file:</p>
<pre class="lang-cpp prettyprint-override"><code>template &lt;uint8_t ARRAY_SIZE&gt;
class buttonArrayTFT
{
public:
// One thing to remember about templates: you have to pack the definition
// into the header file with the declaration to avoid all manner of headaches.

    buttonArrayTFT(XPT2046_Touchscreen &amp;_ts = ts, Adafruit_ILI9341 &amp;_tft = tft)
    {
    // Perhaps this is a good opportunity to check that the specified
    // size of the array is sensible, i.e. not zero and no more than 12.
        if ((ARRAY_SIZE == 0) || (ARRAY_SIZE &gt; 12))
        {
            // decide how you want to handle this problem
        }
            // Add the rest of your constructor here
    }

    void create_array(uint8_t R, uint8_t C, char *but_txt[]);
    uint8_t checkPress(TS_Point &amp;p);
        
    // This little piece of magic allows you to access buttonTFT 'x' of the
    // private _buttonArray as if a buttonArrayTFT class was an array
    buttonTFT &amp;operator[](uint8_t index)
    {
    // Check that 'index' is a valid element in the array
        if (index &gt; _num_items)
        {
            // decide how you want to handle this problem
        }
        return _buttonArray[index];
    }
private: 
    buttonTFT _buttonArray [ARRAY_SIZE];
    // I recommend making this constant
    const uint8_t _num_items = ARRAY_SIZE;
};
</code></pre>
<p>I shall leave it up to you to sort out your privates, publics and protecteds, and I have left out <code>ButtonTFT _button0;</code> to keep you on your toes.</p>
<p>You'll also notice that the array is private, as before, but there is now no array-of-pointers-to-buttons. This is because there is no need; the magic <code>buttonTFT &amp;operator[](int index)</code> allows you to access array elements directly.</p>
<p>In your <em>.ino</em> file, or as appropriate, you use the following code to create and then wield the class:</p>
<pre class="lang-cpp prettyprint-override"><code>buttonArrayTFT&lt;4&gt; myFourButtonArray(/* constructor arguments as required*/);
buttonArrayTFT&lt;12&gt; myTwelveButtonArray(/* constructor arguments as required*/);
</code></pre>
<p>This gives you two instances of the class, with the respective number of <code>buttonTFT</code> elements! You can now access specific buttons using the following code:</p>
<pre class="lang-cpp prettyprint-override"><code>myFourButtonArray[0];    // Returns a reference to the first buttonTFT
myTwelveButtonArray[10]; // Returns a reference to the eleventh buttonTFT
myFourButtonArray[n]     // Returns a reference to the 'n+1'th buttonTFT
</code></pre>
<p>On the assumption that the <code>buttonTFT</code> class has some kind of 'read' function that returns a TRUE or FALSE for the status of the button, you can write:</p>
<pre class="lang-cpp prettyprint-override"><code>if (myFourButtonArray[0].read())
{
    // executed if the button is ON
}
else
{
    // executed if the button is OFF
}
</code></pre>
<p><strong>A NOTE ON CONST-NESS:</strong></p>
<p>The overloading of <code>operator[]</code>, while wonderfully magic, is open to abuse. However, this is no different from your original code. The array of <code>buttonTFT</code> elements is private but there is public access to all the buttons almost as if the array was not private. In the case of your original code, one could write:</p>
<pre class="lang-cpp prettyprint-override"><code>myButtonArray._buttons[0] = myButtonArray._buttons[1];
</code></pre>
<p>Now <code>_buttons[0]</code> <em>points to the same buttonTFT</em> as <code>_buttons[1]</code>.</p>
<p>Ouch. Now <code>myButtonArray._buttons[0]-&gt;read()</code> is literally the same thing as <code>myButtonArray._buttons[1]-&gt;read()</code>.</p>
<p>That said, my code does not make it a great deal better; the equivalent code:</p>
<pre class="lang-cpp prettyprint-override"><code>myFourButtonArray[0] = myFourButtonArray[1];
</code></pre>
<p>Simply <em>copies</em> the right hand side over to the left hand side. You still have two distinct <code>buttonTFT</code> instances, with probably no memory leaks, but I am guessing that <code>buttonTFT</code> class may contain a reference to an Input pin, so the <code>_button[0]</code> pin will now be whatever <code>_button[1]</code> pin is because the member variable that stores the pin reference will be overwritten.</p>
<p>To solve this weakness, simply add the <code>const</code> qualifier to the beginning of the <code>operator[]</code> overload:</p>
<pre class="lang-cpp prettyprint-override"><code>const buttonTFT &amp;operator[](uint8_t index)
{ // };
</code></pre>
<p>Now the <code>buttonTFT</code> element cannot be altered. This of course brings in a new headache that all functions that rely on <code>myArray[n]</code> also need to be constant. It is up to you to determine how constant correctness should be interpreted and whether it is worth the hassle.</p>
