2017-01-01 9 views
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

을; }'해야합니까? – 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을 고려하십시오.귀하의 질문에 코멘트 (정적 멤버보다는 싱글 톤 클래스 사용) – 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) 
     { 
      /* .... */ 
     } 
    } 
}; 

을에서 시간을 컴파일되지 않지만, 동일한 효과를 가지고있다.

템플릿 기반 접근 방식을 사용하면 두 개 이상의 클래스 인스턴스를 만들 수 있습니다. 어떤 당신이 다른 것은이 최신 Atmel의 프레임 워크는 벡터의 헤더가 포함되어 있지 않습니다 있다는 것입니다

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++ 표준 라이브러리가 없다. 일하고있어. – rrd

+0

C++ 표준 라이브러리가 없다면 어떤 라이브러리를 사용하고 있습니까? – tinstaafl

+0

저는 Atmel AVR 마이크로 컨트롤러를 프로그래밍하고 있습니다. 해당 플랫폼에는 공식 C++ 라이브러리가 없습니다. – rrd