>

다양한 구체적인 클래스가 상속하는 상태 비 저장 추상 기본 클래스가 있습니다. 이 파생 클래스 중 일부는 상태 비 저장입니다. 많은 것들이 실행 중에 만들어지기 때문에 모든 stateless 파생 클래스가 연산자 new ()/delete ()를 재정 의하여 단일 상태를 모방하여 메모리와 오버 헤드를 절약하고 싶습니다. 간단한 예는 다음과 같습니다.

#include <memory>
struct Base {
  virtual ~Base() {}
 protected:
  Base() {}   // prevent concrete Base objects
};
struct D1 : public Base {  // stateful object--default behavior
  int dummy;
};
struct D2 : public Base {  // stateless object--don't allocate memory
  void* operator new(size_t size)
  {
    static D2 d2;
    return &d2;
  }
  void operator delete(void *p) {}
};
int main() {
  Base* p1 = new D1();
  Base* p2 = new D1();
  Base* s1 = new D2();
  Base* s2 = new D2();
  delete p1;
  delete p2;
  delete s1;
  delete s2;
  return 0;
}

이 예제는 작동하지 않습니다 : delete s2;   delete s1; 때문에 실패   ~Base() 라고 공유 Base 를 할당 해제했습니다.  와이즈 비즈 . 이것은 새로운/삭제 오버로드와 동일한 트릭을 기본에 추가하여 해결할 수 있습니다. 그러나 이것이 가장 깨끗한 솔루션인지, 심지어 올바른 솔루션인지 확실하지 않습니다 (valgrind는 불평하지 않습니다, FWIW). 조언이나 비평에 감사드립니다.

편집 : 실제로 상황은 더 나쁘다. 내가 주장한 것처럼이 예제의 Base 클래스는 추상적이지 않습니다. 순수한 가상 메소드를 추가하여 추상적 인 경우 Base 유형의 정적 변수를 가질 수 없으므로 새/삭제 재정의 트릭을 더 이상 적용 할 수 없습니다. 따라서이 문제에 대한 해결책이 없습니다!

d2

  • 답변 # 1

    여기서 가장 좋은 해결책은 파생 클래스를 실제 싱글 톤으로 만드는 것입니다. 파생 생성자를 비공개로 만들고 필요한 개체를 만들거나 정적 인스턴스를 반환하는 정적 Base * getInstance () 메서드를 제공하십시오. 이렇게하면 새로운 D1을 호출하는 것은 불법이기 때문에 D1 객체를 얻는 유일한 방법은이 방법을 사용하는 것입니다.

  • 답변 # 2

    그럴 수는 없습니다. 각 개체에는 고유 한 주소가 있어야합니다. 각 객체에 별개의 메모리 블록을 할당해야합니다. operator new 를 재정의하면 다소 빠르게 수행 할 수 있습니다.  고정 크기의 객체에 맞게 특별히 설계된 빠른 블록 할당기를 사용합니다.

관련 자료

  • 이전 c# - AssemblyCreateInstance 및 보안
  • 다음 java - 정적 메서드 내에서 인스턴스화 된 익명 내부 클래스가 클래스를 포함하는 인스턴스 멤버에 액세스 할 수 있습니까?