2011-02-02 2 views
2

직접 질문 : 클래스 개체의 복사본이 3 개 (또는 그 이상) 거의 동일하면 어떻게 그 개체 간의 차이점을 가장 잘 (또는 가장 효율적으로) 저장할 수 있습니까?클래스 개체의 복사본이 3 개 * 약간 다를 경우 어떻게 효율적으로 차이점을 저장할 수 있습니까?

배경 : I 매개 변수의 집합을 필요로하는 알고리즘이 있습니다

struct params 
{ 
    std::string A; 
    std::string B; 

    double C; 
    double D; 

    userDefinedTypeDef S; 
}; 

을 그리고 내 알고리즘을 세 번 전화를 걸. 처음에는 C = 3 & S = 'foo'입니다. 두 번째로, C = 4 & S = 'foo'. 그리고 세번째로, C = 4 & S = 'bar'. 주어진 예는 설명을위한 것일뿐 실제 개체는 구조가 아닌 클래스이며 몇백 명의 구성원이 있습니다. 알고리즘을 세 번 이상 호출하고 싶기 때문에이 객체의 여분의 복사본을 가지고 싶지는 않습니다. 그렇다면 두 클래스 객체 간의 차이점 만 저장하는 가장 좋은 패턴/구현/방법은 무엇입니까?

즉, "개체 2는 & (개체 1)과 동일하지만 C = 4"와 다를 수 있습니다.

편집 : : 아래 코멘트에서 언급했듯이 매개 변수 클래스 개체 또는 멤버 개체의 배열뿐만 아니라 함수 호출도 변경하지 않는 것이 좋습니다. 그렇게하기위한 나의 목적은 하나의 복사본을 유지하고, "currentParam"이라고 주장한 다음 연속 호출 간의 차이점 목록을 유지하는 것입니다. 그렇게하면, 변경된 값을 간단히 업데이트 할 수 있고, 나머지는 고정되어 있으며, 주어진 함수를 사용합니다.

그렇다면 가장 쉬운 방법은 무엇일까요? 부울 플래그 'member1_changed'가있는 클래스를 만드시겠습니까? 그런 다음 노동 조합을 사용합니까? 나는 꽤 갇혀있다. 희소 한 매트릭스 스토리지에 대해 약간의 수수께끼와 관련이있을 수있다. 그래서 나는 왜 질문을 던졌다.

+0

[이 질문] (http://stackoverflow.com/questions/52400)도 관련 될 수 있습니다. –

+0

이러한 개체에 대해 무엇을 알고 있습니까? 일부 입력에서 연속 된 전체 물체를 읽고 델타를 계산합니까, 아니면 델타를 직접 읽습니까? 하나의 전체 객체 만 메모리에 저장하고 순서를 유지하려는 경우 각 델타는 이전 객체의 객체 여야합니다. 합리적으로 각 델타를 (field ids + boost :: any 또는 variant 또는 home-spun-union)의 컨테이너로 인코딩하고 클래스에 해당하는 업데이트 함수를 제공 할 수 있습니다. –

+0

전체 개체를 만드는 대신 델타를 직접 만들고 싶습니다. –

답변

4

Flyweight design pattern이 관심의 대상입니다. 그것은 당신의 문제를 해결하기 위해 특별히 고안되었습니다.

1 단계 :

다음은 차이를 저장하는 하나의 방법 멤버에 대한 포인터로 모든 멤버를 교체합니다. 예, 약간의 메모리 오버 헤드가 추가됩니다.

2 단계 : 클래스에 딥 복사본 대신 공유 구성원의 얕은 복사본이 저장되어 있습니다.

클래스가 변경 가능하지 않으면이 기술은 더욱 복잡해 지지만 기본 아이디어는 여전히 실행 가능합니다.

이렇게하면 메모리 사용량이 줄어들지 만 메모리 참조의 공간적 지역성도 감소합니다. 이로 인해 프로그램 속도가 크게 느려질 수 있습니다. 또한 간접 지정의 추가 레이어를 추가합니다.

+0

+1, 논의 된 제안이 패턴 그 자체와 다소 다르긴하지만. –

1

몇백 명의 회원이 있습니까? 그게 나에게서 나에게 나쁜 디자인의 권리처럼 들린다. 나는 많은 것들이 필요한 묘사 할 수있는 대상을 생각조차 할 수 없다. 나는하는 시스템을 생각할 수있다. 하지만 공정하게 말하면, 나는 당신이 원래 이것을 썼는지조차 알지 못하기 때문에 당신을 비판하지 않습니다. 지능적으로 클래스를 하위 클래스로 분리하거나 데이터를 더 나은 표현으로 그룹화 할 수있는 방법을 살펴 보겠습니다. 그것은 첫 번째 시작입니다.

void foo(Bar _objectWithTonsOfMembers){ //stuff... 

당신은 당신이 생각할 수있는 일했다고하면

void foo(int itemCount, double price, double discount, Customer customer){ //stuff 

로 : 그것에서 작동 그냥 매개 변수를 받아들이도록

그 후 나는 또한 아마 함수를 다시 작성보고 싶은데 다른 매개 변수로 요청을 처리하는 방법. 이러한 상황과 정확히 처리 할 때 Boost::BindBoost::Function과 결합하는 데 도움이 :

boost::function<void(int,double)> refinedFoo = boost::bind(foo, _1, _2, 4.09, Customer("Pam")); 
refinedFoo(1, 3.0); 
refinedFoo(2, 2.0); 

가 지금은 쉽게 만 변경하는 매개 변수와 함께 내가 원하는 함수를 호출 할 수 있습니다.

편집 :

은 내가 무엇을 의미하는지 명확히하기 위해 "서브 클래스를,"차라리 구조를 상속 만에 언급되지 않았다.그러므로 나는 여러분에게 어떤 클래스 "Foo"를 가져 와서 클래스 바, Baz, Biff, 그리고 Bam 클래스의 구성으로 만들길 바랍니다. 이들은 코드 내에서 사용되는 것처럼 논리적 인 요소로 분류되어야합니다.

그리고 4 개의 멤버 변수 만 작동하는 함수가 있고 그 멤버 변수가 일반적으로 항상 같은 방식으로 작동하면 새 클래스 나 구조체를 만드는 것이 좋습니다.

+0

나는 조금 지나치게 단순화 시켰을지도 모른다. 네, 복사본을 만들고 싶지 않은 오브젝트는 실제로 A2가 A에서 파생되고 B2가 B에서 파생되는 등 8 개의 하위 클래스 (A, A2, B, B2, C, D, E, F)를가집니다. 알고리즘은 통계 샘플러이며 실제로 후속 호출간에 다를 수있는 하위 클래스 중 하나 또는 두 개만 필요합니다. 필자는 본질적으로 함수를 변경할 수있는 유연성이 없지만 마찬가지로 모든 하위 클래스 멤버를 배열로 변환하지 않는 것을 선호합니다. –

+0

@M. Tibbits 내가 하위 클래스를 말했을 때 나는 상속을 의미하지는 않았지만 내 응답과 구별하기가 어렵습니다. 나는 A를 몇 개의 다른 클래스로 나눠서 A가 그 클래스의 조합임을 의미했습니다. 명확히하기 위해 내 대답을 수정하겠습니다. – wheaties

+0

나는 당신이 무엇을 의미 하는지를 이해했다고 믿지만, 나는 더 많은 정보를 제공한다. - 매개 변수 객체 (A, A2, B, B2, C, D, E, F)에서 F는 단지 typedef 'algType'이다. 알고리즘 유형에 따라 함수 Sample (param)은 A, A2, B, B2, C, D 또는 E 하위 클래스 중 하나가 필요한 다른 샘플러를 호출합니다. 연속 클래스 사이에서 A 멤버는 다를 수 있습니다. F 변경 될 수도 있고, 아마도 B가 변경 될 수도 있습니다.하지만 내가 한 방식대로 질문을하는 것이 요점입니다. 함수 정의를 변경할 수 없으며 구성을 변경하여 A, A2 등 –

관련 문제