1

I'm writing a class I don't want to instantiate. All its members are static. This class represents a peripheral of a microcontroller. Since there is only one instance of that peripheral in the microcontroller doesn't make sense to me create instances of that class. The class only groups the data and functions of that peripheral.

One of the data members of the class is an array whose size the user of the class should define at compile time. If I could create objects of this class I know I could initialize consts in the initializer list of a constructor, but I really don't want to create instances of this class. Maybe I could use templates and set the array size as the template parameter, but I would need to use something like my_class<5>::do_something() for every member call. Is there a simpler way to solve this problem? I'd like to make my class something like this:

class my_class
{
private:
    static const int _size;
    static int _array[_size];
public:
    static void array_size(int size) { _size = size; }
    static void do_something() { /* .... */ } 
};

4 Answers4

2

Consider using class template parametrized with constexpr array size and then create an alias:

#include <array>

template <std::size_t Size>
class my_class_impl {
private:
    static constexpr std::size_t size = Size;
    static std::array<int, Size> arr;
public:
    static void do_something() { /* .... */ }
};

template <std::size_t Size>
std::array<int, Size> my_class_impl<Size>::arr;

using my_class = my_class_impl<10>;

int main() {
    my_class::do_something();
}
W.F.
  • 13,888
  • 2
  • 34
  • 81
1

Your best bet is probably a good old define.

Here's how I'd structure this (using namespaces, as it's the idiomatic way to do static-only classes):

peripheral.h:

namespace peripheral {
  void do_something();
}

peripheral.cpp:

#ifndef PERIPH_ARRAY_SIZE
#  error "please define the size of array"
#endif

namespace {
  int _array[PERIPH_ARRAY_SIZE];
}

namespace peripheral {
  void do_something() {...}
}
0

Your main requirement is that the array size is set at compile time. This is more C-ish, something you'd generally avoid when writing C++, but in your case, it might make more sense to use macros, such as

#define ARRAY_SIZE 
... somewhere in your class ...
static int array_name[ARRAY_SIZE];
mgarey
  • 733
  • 1
  • 5
  • 19
  • Actually I'm using macros right now, but this class will be part of a library. I'd like to allow the user to define the size of the array in code instead of using -DARRAY_SIZE flag while compiling. –  Jan 01 '17 at 17:13
  • Just to clarify: When you say "part of a library," do you mean that the user must statically link said library to their code? – mgarey Jan 01 '17 at 17:16
  • If that's the case, consider n.m.'s comment in your question (using a Singleton class rather than static members) – mgarey Jan 01 '17 at 17:18
  • could you say more about this? I don't know how to implement a singleton. I also don't know what are the advantages of this approach instead of my class with static members. –  Jan 01 '17 at 17:22
  • This answer shows how to implement a Singleton: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 – mgarey Jan 01 '17 at 17:23
0

One way to allow the user to set the size, would be to change the array to a vector. Since it's private you control how it's used. A simple bool will restrict whether it's sized once and making sure it does get sized:

class my_class
{
private:
    static const int _size = 10;
    static vector<int> _array;
    static bool arraySized;
public:
    static void array_size( int size = _size ) 
    {
        if ( !arraySized )
        {
            _array = vector<int>( size );
            arraySized = true;
        }
    }
    static void do_something() 
    {
        if ( arraySized )
        {
            /* .... */
        }
    }
};

While not at compile time, it does have the same effect.

A couple of other things to think about, using a template based approach can allow more than 1 instance of that class to be created. Which can break the singularity principle that you seem to want

using my_class = my_class_impl<10>;

using my_class2 = my_class_impl<20>;
int main() {
    my_class::do_something();
    my_class2::do_something();
}

The other thing is that the newest Atmel framework does include headers for vectors. The information you referenced must be out of date.

tinstaafl
  • 6,908
  • 2
  • 15
  • 22
  • Thanks, but I don't have the C++ std library is the platform I'm working. –  Jan 01 '17 at 17:26
  • If you don't have the C++ std library, which library are you using? – tinstaafl Jan 01 '17 at 17:28
  • I'm programming an Atmel AVR microcontroller. There's no official C++ library for that platform. –  Jan 01 '17 at 19:56
  • So then, assuming you're using Atmel Studio, you should be able to use anything that's in the C++ std library. vectors are part of the C++ std library. It' just a matter of including the right header. – tinstaafl Jan 01 '17 at 20:25
  • http://www.atmel.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_cplusplus.html –  Jan 01 '17 at 20:32
  • I added more info for you. – tinstaafl Jan 02 '17 at 20:43
  • Thanks! Can you link the source of that information, please? I made a search in the web and looks like there's nothing about that. –  Jan 04 '17 at 15:38
  • I installed the Atmel Studio and found the header in the include folders. It did require burrowing down a little. it was `#include ` – tinstaafl Jan 04 '17 at 16:04