새로운 것을 사용하지 않고 C ++에서 공장 메소드 패턴을 구현할 수 있습니까?
-
06-07-2019 - |
문제
나는 임베디드 환경 (Arduino/Avr Atmega328)에서 일하고 있으며 C ++에서 공장 방법 패턴을 구현하려고합니다. 그러나 내가 사용중인 컴파일러 (AVR-GCC)는 new
예어. 사용하지 않고이 패턴을 구현하는 방법이 있습니까? new
?
해결책
AVR 컴파일러는 GCC 컴파일러를 기반으로하므로 새로운 키워드를 지원할 가능성이 높습니다. 당신이 얻는 오류는 정확히 무엇입니까? 나는 그것이 정의되지 않은 함수, 즉 연산자 새로운 라인을 따라 링크/컴파일러 오류라고 생각합니다. 새 연산자와 연산자가 새로 차이가 있는데, 첫 번째는 객체를 만드는 데 사용되며 후자는 객체에 메모리를 할당하는 데 사용됩니다. 새 연산자는 생성중인 객체 유형에 대해 연산자를 새로 호출 한 다음 객체의 v-table을 초기화하고 객체의 생성자를 호출합니다. 이 FAQ를 읽습니다 Operator New는 표준 라이브러리에서 정의되지 않았다고합니다. 이것은 쉽게 해결할 수 있습니다.
void *operator new (size_t size)
{
return some allocated memory big enough to hold size bytes
}
삭제도 정의해야합니다.
void operator delete (void *memory)
{
free the memory
}
추가해야 할 유일한 것은 메모리 관리, 메모리 블록의 할당 및 해방입니다. 이는 기존 할당 된 메모리 (코드, 정적 / 글로벌 데이터, 스택)를 클로브하지 않도록 조심스럽게 이루어질 수 있습니다. 두 개의 기호가 정의되어 있어야합니다. 하나는 자유 메모리의 시작과 하나는 자유 메모리의 끝을 위해 정의되어야합니다. 이 영역에서 모든 메모리 덩어리를 동적으로 할당하고 자유롭게 할 수 있습니다. 이 메모리를 직접 관리해야합니다.
다른 팁
런타임에 클래스를 인스턴스화 할 방법이 없다면 이것이 불가능하다고 생각합니다. 당신이 할 수있는 것은 컴파일 시간에 일부 객체를 사전 할당하고, 참조를 작성하고 필요할 때 반환하는 것입니다.
공장 방법의 큰 그림은 객체 생성입니다. 이는 힙 메모리 소비를 의미합니다. 임베디드 시스템에서는 RAM에 의해 제약을 받고 메모리 제한을 염두에두고 모든 설계 결정을 내려야합니다. ATMEGA328에는 2kb RAM 만 있습니다. 그런 긴밀한 공간에서 동적으로 할당 된 메모리를 사용하는 것이 좋습니다.
당신의 문제를 더 자세히 알지 못하고, 나는 수업의 소수의 사례를 정적으로 선언하고 어떤 방식으로 그러한 사례를 재사용하는 것이 좋습니다. 이것은 당신이 당신의 객체가 언제, 왜 만들어 졌는지, 그리고 그것이 언제, 그리고 왜 그들이 끝나는지를 알아야한다는 것을 의미합니다. 그런 다음 한 번에 얼마나 많은 활동을 해야하는지, 한 번에 활동할 수 있는지 알아 내야합니다.
!!학장
이와 같은 것은 어떻습니까?
MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass(); // or any other c'tor
편집 : 언급을 잊어 버렸습니다. MyClass에 과제 연산자가 있다고 가정합니다.
edit2 : 내가 잊어 버린 또 다른 것 - 예, gotcha가 있습니다 (C ++, 항상 gotchas가 있습니다). 무료로 사용할 수 없으므로 객체에 대해 D 'Tor를 수동으로 호출해야합니다.
공장을 사용하는 경우 가상 기능이 있음을 나타내는 동적 바인딩 동작을 원한다는 것을 의미합니다. 그러나 malloc ()를 사용하여 객체에 대한 메모리를 할당하는 것이 가능할 수 있지만 클래스의 vtable은 제대로 설정되지 않으므로 가상 함수에 대한 호출이 중단됩니다. 동적 바인딩이 필요할 때이 작업을 수행하는 방법이 보이지 않습니다.
Malloc을 할 수 있습니까? 그렇다면 그런 식으로 물체를 malloc 할 수 있습니다.
또한 공장에서 만들고 싶은 객체의 특성은 무엇입니까?
- 그들은 흉내낼 수 있습니까?
- 공장은 컴파일 타임에 알 수있는 제한된 객체 세트 만 생성하기위한 것입니까?
대답이 두 질문 모두에 예술이라면, 불변의 객체 세트에 대한 메모리를 정적으로 할당하고 공장 방법이 포인터를 적절한 개체에 반환하도록 할 수 있습니다.
대답이 어느 질문에도 없다면 이것은 작동하지 않습니다. 또한이 접근법은 항상 메모리를 할당하는 데 문제가 있습니다.
엄격한 코딩 표준 ( "신규"또는 "삭제"를 사용할 수없는 경우)을 가진 임베디드 시스템 에서이 문제를 해결하는 방법은 원하는 객체의 정적 배열을 만드는 것입니다. 그런 다음 이미 할당 된 객체에 정적 포인터를 사용하여 다양한 객체의 나중에 실행하기 위해 이러한 반환 된 값 (정적 변수 및/또는 멤버 변수 사용)을 저장하십시오.
// Class File ---------------------------------------------------
class MyObject {
public:
MyObject* getObject();
private:
const int MAX_POSSIBLE_COUNT_OF_OBJECTS = 10;
static MyObject allocatedObjects[MAX_POSSIBLE_COUNT_OF_OBJECTS];
static allocatedObjectIndex = 0;
};
// Implementation File ------------------------------------------
// Instantiate a static array of your objects.
static MyObject::allocatedObject[MAX_POSSIBLE_COUNT_OF_OBJECTS];
// Your method to return already created objects.
MyObject* MyObject::getObject() {
if (allocatedObjectIndex < (MAX_POSSIBLE_COUNT_OF_OBJECTS - 1)) {
return allocatedObjects[allocatedObjectIndex++];
} else {
// Log error if possible
return NULL;
}
}
예언하십시오. 8 개월 이상 C ++를 작성하지 않았기 때문에 이것은 모두 메모리에서 비롯됩니다.
또한 참고 : 이것은 컴파일 타임에 많은 RAM을 할당한다는 점에서 심각한 단점이 있습니다.