2014-10-15 2 views
0

AVR CPU 용 클래스를 개발 중입니다.컴파일 타임에 클래스 인스턴스가 하나만 있는지 확인

클래스는 Set, Read 등과 같은 모든 포트 관련 작업을 처리합니다. 생성자는 다음과 같습니다

(...) 
public: 
    Port(volatile uint8_t * DDR, volatile uint8_t * PORT); 
(...) 

그리고는 main()의 시작 부분에 구성된다 :

int main() 
{ 
    Port PortA(&DDRA, &PORTA); 
    (...) 
} 

가 지금은 어디에서도 동일한 매개 변수를 사용하여 프로그램 객체가 구축 될 수 있는지 확인하려면. 그것을 발견하고 예외를 throw 배열 또는 맵을 만들 수 없다는 것이 확실합니다. 컴파일 할 때 수행해야합니다. 그래서 근본적으로 저는 현재의 프로젝트에서 다른 포트 (동일한 첫 번째 매개 변수 또는 두 번째 매개 변수)가 존재하는지 확인하기 위해 avr-g ++을 강제 실행하려고합니다.

모든 함수는 Port 개체에 대한 포인터/참조를 사용합니다.

+6

[싱글 톤 패턴] (http : //en.wikipedia.org/wiki/Singleton_pattern). –

+0

atmega에서 'new'및 'delete'를 사용하는 것이 가장 좋은 생각이 아닙니다. – peku33

+1

@ peku33 배치를 새로 사용하거나 정적 변수를 사용할 수 있습니다. – Anycorn

답변

2

다음은 어때요?

포인터의 주소는 컴파일시 알려 져야합니다.

template<int *p> 
class Tester 
{ 
public: 
    static Tester& GetInstance() 
    { 
     static Tester t; 
     return t; 
    } 

private: 
    Tester() {} 
}; 

int i; 

int main() 
{ 
    Tester<&i>& t = Tester<&i>::GetInstance(); 
} 
+0

템플릿 개념을 모르는 사람을 위해주의를 기울여야합니까? 필자는 주로 임베디드 프로그래밍을 위해 C를 사용합니다. –

+0

@ Rev1.0 템플릿의 사용법이 상당히 고급이어서 간단히 설명하기가 어렵습니다. 템플릿 매개 변수로 제공된 각 포인터 주소에 대해 새 클래스 유형이 정의됩니다. 생성자를 비공개로 만들면 해당 포인터 주소에 대한 클래스 유형의 수를 정확하게 제어 할 수 있습니다. –

+0

고맙습니다.이 말을 읽어보기로 마음 먹으면 올바른 방향으로 포인터 (no pun : P)를줍니다. –

-1

이것은 꽤 아니지만 일을 처리합니다. 10 년의 경험에 따르면 임베디드 작업은 때때로 이와 같은 경향이 있습니다. :/

MSVC에서 간단한 클래스로 테스트 했으므로 사용자의 요구에 맞춰야하지만 원리를 입증 할 수 있습니다.

이 헤더에 다음과 같이 클래스를 선언 :

class t 
{ 
public: 
#ifdef ALLOW_CTOR 
    t(int i); 
    ~t(); 
#endif 
    int get(); 

private: 
    int m_i; 
}; 

그리고 정확히 하나의 파일에 줄을 추가 :

#define ALLOW_CTOR 1 

이 헤더 파일을 포함을, 파일 범위 변수로 포트 인스턴스를 선언, 클래스, ctor, dtor, 접근 자 등의 모든 클래스 메서드를 구현하십시오.

다른 소스 파일에 ALLOW_CTOR 행을 배치하지 않으면 th ey은 여전히 ​​클래스에서 접근 자 메서드를 사용할 수 있지만 생성자는 사용할 수 없습니다. 올바른 생성자가없는 경우 MSVC는 기본 복사 생성자를 사용하려고하기 때문에 불만하지만 매개 변수 목록이 일치하지 않으므로 실패합니다. 나는 당신이 사용하고있는 컴파일러가 어떤 식 으로든 실패 할 것이라고 생각한다. 나는 그 실패가 정확히 무엇인지 확신 할 수 없다.

+1

이것은 정의되지 않은 동작입니다. –

+0

C++ 표준의 어느 부분에 있습니까? – dgnuff

+1

클래스 정의는 소스 파일 포함간에 일관성이 있어야합니다. 모든 매크로 값은 동일해야합니다. 나는 그 절을 모른다. –

0

클래스의 인스턴스 하나만 원한다면 클래스를 사용해야하는 이유는 무엇입니까? 클래스의 전체 목적은 여러 가지 intances를 가질 수 있다는 것입니다. 그냥 전역 변수와 자유 함수에 충실하십시오.

+0

DDR 및 기본 포트 ADDR에 대해 서로 다른 주소를 가진 Port 클래스의 인스턴스가 여러 개 있기 때문입니다. 그는 Port 클래스의 두 인스턴스가 동일한 하드웨어를 참조하려고 할 때 ** 발생할 수있는 문제를 피하려고합니다. – dgnuff

-1

는 @Neil 커크

컴파일 단위에 대해 전혀 ctor에의 선언을 제공하기 위해 실패가 정의되지 않은 동작에 이르게되면

, 그를 해결하는 방법이 있습니다.

class t 
{ 
#ifdef ALLOW_CTOR 
public: 
#else 
private: 
#endif 
    t(int i); 

public: 
    ~t(); 
    int get(); 

private: 
    int m_i; 
}; 

은 ctor를 하나의 공용으로 표시하지만 다른 모든 컴파일 단위에는 개인으로 표시하여 잘 정의 된 오류 인 개인 회원 기능에 액세스 할 수 없습니다.

+0

문제가되는 생성자의 존재 또는 부재가 아닙니다. 여러 소스 파일에서 관찰되는 일관성없는 정의가 도입되는 것은 사실입니다. 그것이 UB입니다. –

관련 문제