2017-01-01 9 views
1

私はインスタンス化したくないクラスを書いています。すべてのメンバは静的です。このクラスは、マイクロコントローラの周辺機器を表します。マイコンにその周辺機器のインスタンスが1つしかないので、私はそのクラスのインスタンスを作成することに意味がありません。クラスは、その周辺機器のデータと機能だけをグループ化します。インスタンス化不可能なクラスの静的メンバーである配列のサイズを定義する方法はありますか?

クラスのデータメンバーの1つは、クラスのユーザーがコンパイル時に定義するサイズの配列です。このクラスのオブジェクトを作成できれば、コンストラクタのイニシャライザリストでconstを初期化できますが、実際にはこのクラスのインスタンスを作成したくありません。たぶん私はテンプレートを使用し、テンプレートのパラメータとして配列のサイズを設定することができますが、私は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

サイズは、コンパイル時に設定されている場合、 '静的ボイドARRAY_SIZE(int型のサイズ){_size =サイズが何であります。 } 'やるべきことは? – wally

+0

シングルトンクラスを考えてみましょう。それは、普通の古い静的データよりもいくつかの利点があります。 –

+0

@ n.m。もっと詳しくお聞かせください。 – rrd

答えて

3

constexprのアレイサイズでパラメータ化クラステンプレートを使用して検討した後、エイリアスを作成する:

#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。あなたの質問のコメント(静的メンバーではなくシングルトンクラスを使用) – 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

ユーザーがサイズを設定できる方法の1つは、配列をベクターに変更することです。プライベートなので、使用方法を制御します。単純なブールでは、一度サイズを決めてサイズが正しくなっているかどうかを制限します。

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

コンパイル時ではなく、同じ効果があります。

テンプレートベースのアプローチを使用すると、そのクラスのインスタンスを2つ以上作成することができます。それはあなたが他の事は、最新アトメルフレームワークはベクトルのヘッダーが含まれないことである

using my_class = my_class_impl<10>; 

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

たいように見えるという特異点の原則を破ることができます。あなたが参照した情報は古いものでなければなりません。

+0

ありがとうございますが、私はC++標準ライブラリがプラットフォームIではありません私は働いています。 – rrd

+0

C++標準ライブラリがない場合は、どのライブラリを使用していますか? – tinstaafl

+0

私はAtmel AVRマイクロコントローラをプログラミングしています。そのプラットフォーム用の公式のC++ライブラリはありません。 – rrd

関連する問題