2010-06-09 2 views
8

최근에 iPhone 용 개발을 한 끝에 iPhone SDK에서 객체 변경과 관련하여 많이 사용 된 흥미로운 디자인 패턴에 주목했습니다.Objective C 및 C++의 무손실 디자인 패턴

변경 불가능한 클래스 NSFoo을 정의한 다음 변경 가능 하위 클래스 NSMutableFoo을 파생시키는 것이 일반적인 방법 인 것처럼 보입니다. 일반적으로 NSFoo 클래스는 데이터 멤버, getter 및 읽기 전용 작업을 정의하며 파생 및 파생 된 파생 된 파서 및 변형 작업을 수행합니다.

C++에 익숙해 졌기 때문에 C++에서 동일한 코드를 작성할 때와 완전히 반대되는 것으로 보입니다. 확실히 그 접근 방식을 취할 수 있지만 더 간결한 접근 방식은 하나의 Foo 클래스를 만들고, getters 및 읽기 전용 작업을 const 함수로 표시하고 같은 클래스에서 변경 가능한 연산과 설정자를 구현하는 것으로 보입니다 . 그런 다음 변경 가능한 클래스로 끝나지 만 유형이 Foo const*, Foo const& 등이 모두 사실상 변경 불가능한 동급 클래스입니다.

제 질문은 내 상황을 이해하는 것이 합리적입니까? Objective-C가 다른 방식으로 동작하는 이유를 이해하지만 C++의 두 가지 클래스 접근 방식에 대해 내가 놓친 이점이 있습니까? 아니면 완전히 그 요점을 놓치고 있습니까?

지나치게 심각한 질문이 아닙니다. 내 호기심에 대한 것보다.

답변

4

오브젝티브 C도 동적입니다. C++에서 const-qualification은 컴파일 타임에 적용되며 런타임에 const-qualification 위반 (예 : const가 아닌 포인터를 통해 const 한정 오브젝트 수정)은 정의되지 않은 동작입니다.

이는 Objective-C에 개인적인 방법이없는 이유와 부분적으로 같습니다. 원하는 메시지를 원하는대로 보낼 수 있습니다. 런타임 디스패치는 객체와 메시지를 취하고 메소드 구현을 호출하여 호출합니다.

const 한정 개체가 const 인증 된 메서드 만 호출 할 수있는 경우 Objective-C 및 Foundation의 동적 특성이 완전히 망가질 수 있습니다. 이러한 검사는 런타임에 수행해야하기 때문입니다 (첫 번째 검사는 전송되는 메시지가 해결되는지 특정 인스턴스에 대한 const 규정 된 구현 및 인스턴스 자체가 const 한정인지 여부를 판별하기위한 또 다른 검사). 이 이론적 인 예를 생각해보십시오 :

NSArray *mutableArray = [[NSArray alloc] init]; 

NSString *mutableString = @"I am a mutable string"; 
const NSString *immutableString = @"I am immutable because I am const-qual'd"; 

[mutableArray addObject:mutableString]; 
[mutableArray addObject:immutableString]; // what happens?! 

// and what happens here (both immutable and mutable strings would respond 
// to the same selectors because they are the same class): 
[mutableArray makeObjectsPerformSelector:@selector(aMutableOperation)]; 

갑자기 당신은 역학을 잃게됩니다. 지금은 변경 가능하고 변경 불가능한 오브젝트가 변경 불가능하거나 변경 가능한 콜렉션에 함께있을 수 있습니다.

가변적 인 하위 클래스가 있으면 Objective-C의 동적 특성이 유지되고 런타임이 간단하게 유지됩니다. 개인적인 방법에 관해서는 비슷한 주제가있었습니다.

0

생각 ...

맥 여러분이 알다시피, C++, 당신은 "그들의 유일한 관계

  1. 인으로, 서로 다른 두 가지 유형으로"A "와"CONST A "생각할 수 (A)는 "및"A &는, 등등 ...
  2. & "const를 &"에에 const_cast 할 수있다 ""등 ...
  3. 는 "CONST A가"와 "A &을에서 const"암시 적으로 캐스팅 될 수있다 "

컴파일러는 표현식 등을 통해 유형 수정 자의 상속과 전파를 처리합니다.

NS 사람들이 몇 가지 이유 때문에 .. 관례를 선택했다고 생각합니다. 내 첫 번째 추측은 NextStep이 원래 개척되었을 때 C가 "const"에 대한 지원을하지 않았고 여전히 객체 지향을 갖고 있지 않다는 것을 믿는다는 것입니다. 더 중요한 것은, 변경 가능한 객체 구현과 변경 불가능한 객체 구현에서 특정 최적화를 원했습니다. 예를 들어, NSString과 같은 불변의 문자열 클래스에서는 문자열을 "풀링"하는 것이 유용 할 수 있습니다. 이렇게하면 중복 문자열을 원자화 할 수 있고 프로세스가 잠재적으로 더 적은 메모리를 사용할 수 있습니다. (단점은 있지만, 항상 상충 관계가 있습니다.)

C++에서는 우선 copy-on-write을 이해하면 같은 방향으로 향할 수 있습니다. std :: string은 이렇게합니다.

흥미로운 주제,
윌 브래들리

+1

'std :: string'은 COW를 사용하여 복사시 저장할 수 있지만 표준에서 요구하는 것은 아닙니다. COW는 실제로 다중 스레드 환경에서 성능에 영향을 미치기 때문에 아직 구현이 거의 없습니다. –