2017-01-01 86 views
1

我正在写一个类,我不希望实例。它的所有成员都是静态的。这个类代表一个微控制器的外设。由于微控制器中只有一个外设实例没有意义,因此我无法创建该类的实例。该类仅对该外设的数据和功能进行分组。如何定义非静态类的静态成员数组的大小?

一类的数据成员的是一个数组,其尺寸之类的用户应该在编译时定义。如果我可以创建该类的对象我知道我可以在构造函数中的初始化列表初始化consts,但我真的不希望创建该类的实例。也许我可以使用模板和设置数组大小作为模板参数,但我需要使用像my_class<5>::do_something()为每个成员的呼叫。有没有更简单的方法来解决这个问题?我想让我的课程如下所示:

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() { /* .... */ } 
}; 
+2

; “应该这样做? – wally

+0

考虑一个单例类。它比普通的静态数据有一些优点。 –

+0

@ n.m。,你能说更多吗? – rrd

回答

3

考虑使用与constexpr阵列尺寸参数化类的模板,然后创建别名:如果大小被设置在编译时那么什么是`静态无效ARRAY_SIZE(INT大小){_size =大小

#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(); 
} 
1

您的主要要求是数组大小是在编译时设置的。这是更多的C-十岁上下,东西写C++,当你通常避免,但在你的情况下,它可能会更有意义使用宏,如

#define ARRAY_SIZE 
... somewhere in your class ... 
static int array_name[ARRAY_SIZE]; 
+0

其实我现在正在使用宏,但是这个类将成为一个库的一部分。我希望允许用户在编译时定义数组的大小,而不是使用-DARRAY_SIZE标志。 – rrd

+0

只是为了澄清:当你说“图书馆的一部分”时,你的意思是用户必须静态地将图书馆链接到他们的代码? – mgarey

+0

如果是这样,请考虑n.m.在你的问题中的评论(使用Singleton类而不是静态成员) – mgarey

2

你最好的选择可能是一个很好的旧定义。

以下是我想这个结构(使用命名空间,因为它是做静态只类的惯用方式):

为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

的一种方法,以允许用户设置的大小,将所述阵列改变为载体。由于它是私人的,你可以控制它的使用方式。一个简单的布尔将会限制它是否大小一次,并确保它的大小确定:

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) 
     { 
      /* .... */ 
     } 
    } 
}; 

虽然不在编译时,它确实具有相同的效果。

几个其他的事情要考虑,采用了基于模板的方法可以允许创建该类超过1个实例。这可以打破你似乎想要的奇点原理

using my_class = my_class_impl<10>; 

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

另一件事是,最新的Atmel框架确实包括向量的标头。您引用的信息必须过时。

+0

谢谢,但我没有C++ std库是平台我正在工作。 – rrd

+0

如果您没有C++ std库,那么您使用的是哪个库? – tinstaafl

+0

我正在编程一个Atmel AVR微控制器。这个平台没有官方的C++库。 – rrd