2014-02-14 3 views
2

저는 C++을 약간 알고 있습니다. 이제 Objective-C도 배우려고합니다. 내 책은 클래스 메소드를 간략하게 언급했으며 클래스 메소드는 클래스로 전송 될 수있는 메시지이며 종종 클래스의 인스턴스를 작성하는 데 사용됩니다.목표 C 클래스 메서드 == C++ 생성자?

이것은 클래스 메소드가 C++의 생성자와 비슷하다는 것을 의미합니까? 내 경우에는 Deck 클래스 (현재 C++)가있는 카드 게임을 사용합니다. 나는 그것의 인스턴스를 만들 때, 나는 이렇게 :

Deck *deckWithCards = [Deck newDeck:52]; // A deck with 52 cards with values 
Deck *deckWithoutCards = [Deck newDeck]; // An empty deck 
: 내가 목표 - C에서 같은 일을했다면

Deck deckWithCards(52); // A deck with 52 cards with values 
Deck deckWithoutCards; // An empty deck 

, 그것은 다음과 같이 그것을 할 좋은 "스타일"을 생각하다

클래스 메서드가 올바르게 이해 되었습니까? 클래스 메소드에 다른 용도가 있습니까?

+1

Objective-C에 대한 압축을 알고 있지만 "클래스 메서드"라는 이름과 다른 대부분의 언어에서 사용되는 방식으로 판단하면 C++의'정적 '멤버 함수에 해당합니다. – Angew

+0

ObjC 클래스 메서드와 C++ 정적 멤버 함수는 때때로 "팩토리"함수를 만드는 데 사용됩니다. 팩토리 함수는 객체를 제공하는 것을 목적으로하는 함수입니다 ... 객체 팩토리입니다. 생성자가 관련되면 factory 함수가 생성자 함수를 호출합니다 (제공 한 입력에 따라 다름). C++에서 직접 생성자를 호출하는 것은 팩토리 함수를 사용하는 패턴과 유사하지만 생성자가 객체를 할당하지 않기 때문에 팩토리가 아닙니다. – mah

+0

이렇게 할 수는 있지만 그렇게하지 마시기 바랍니다 **. 팩토리 메소드는 단축키처럼 좋지만 일반적으로'[[object alloc] init]'구문을 사용해야합니다. 이와 같이 단축하고 싶다면, 이미 제공되고있는'new' 클래스 메소드를 사용할 수 있습니다. 바퀴를 재발 명하지 마십시오. – SevenBits

답변

2

즉, 클래스 메소드가 C++의 생성자와 비슷합니까?

정적 멤버 함수와 비슷합니다. 예를 들어, 클래스 메소드의 반환 유형을 지정할 수 있습니다. 그러나 ObjC의 클래스 메서드는 동적 디스패치를 ​​사용합니다.

이니셜 라이저는 생성자와 비슷합니다. 내가 목표 - C에서 같은 일을했다면, 그것은 이런 식으로 작업을 수행하는 "스타일"좋은 생각이다

: ...

정말, 여기에 무슨 분해한다. 이해가되는 편의 생성자를 사용하는 데는 아무런 문제가 없습니다. 일반적으로 편의 생성자를 선언하지 않고 개체의 초기화 자 (접두사가 -init… 인 인스턴스 메서드)를 사용하여 초기화를 사용자 지정합니다.

대신 사용하는 것보다

, +newDeckWithNCards:+newDeck, 당신은 정의 또는 지정된 초기화 대체하여 시작합니다 : 어떤 경우에는

- (instancetype)init; 
- (instancetype)initWithNCards:(NSUInteger)pNCards; 

를, 간이 생성자를 제공하는 것이 편리 할 수 ​​있고, 때때로 당신은을 선호합니다 (많은 사람들이 결코하지 않는) 클래스 클러스터를 구현할 때 클래스 메소드 또는 팩토리가 필요합니다.

대부분의 경우 이니셜 라이저가 적당하지만 일부 경우에는 편의 생성자를 사용하는 것이 나쁘지 않습니다.

클래스 메서드는 훨씬 더 많이 사용될 수 있습니다. 다시 동적 다이나믹 기능을 가진 정적 멤버 함수와 같이 생각하십시오 (따라서 NSString 메서드는 override를 통해 클래스 메서드 내에서 NSMutableString과 다른 구현을 실행할 수 있으며 이는 런타임에 결정됩니다).

2

클래스 메서드는 C++에서 "정적 멤버 함수"라고합니다.

class Deck 
{ 
public: 
    static Deck* newDeck(int cards = 0); 
    // ... 
}; 

// ... 

Deck* deckWithCards = Deck::newDeck(52); 
Deck* deckWithoutCards = Deck::newDeck(); 

을하지만 overloadable 생성자의 존재는 유용하지입니다 :

목표 - C의 "라는 이름의 생성자"관용구

때로는뿐만 아니라 C++에서 사용된다.
또한 RAII와는 잘 어울리지 않습니다.

+0

값이나 스마트 포인터를 반환하면 RAII에 더 친숙해질 수 있습니다. –

-1

아니요, 좋지 않습니다. 이 방법으로 할 수는 있지만 제발하지 마세요! 팩토리 메소드는 단축키처럼 좋지만 일반적으로 [[class alloc] init] 구문을 사용해야합니다. 이와 같이 단축하고 싶다면, 이미 제공된 클래스 메소드 new을 사용할 수 있습니다. 바퀴를 재발 명하지 마십시오.

API와 프로그래머가 방금 한 것처럼 행동했으며 C++와 같은 언어에서 왔음을 즉시 알았습니다.이 같은 것들은 공통적이며 "원시"Objective-C 프로그래머가 아닙니다. C와 유사한 언어는 믿을 수 없을만큼 융통성이 있다는 것을 기억하는 것이 중요합니다. 왜냐하면 무언가를 할 수 있다고해서 반드시해야한다는 것은 아닙니다.

지금 팩토리 메소드는, 당신이 묘사하는 것처럼, 에 어떤 상황,하지만 확실히 아닌 예를 유용합니다. 예를 들어 팩토리 메서드는 stringWithFormat: 같은 곳에서 NSString에 사용되며 그렇지 않으면 기본 패러다임을 사용하여 목에 통증을 유발할 수 있기 때문에 사용되지만 규칙이 아니라 예외입니다.

그냥 내 두 센트.

+0

내 경우에는 갑판 만들기를 어떻게해야합니까? 그것은 : Deck * myDeck = [Deck new]; 그리고 나서 [myDeck setCards : 52]; –

+0

예, 또는 :'Deck * myDeck = [[Deck alloc] initWithCards : 52];'가장 좋은 코코아와 비슷한 방식입니다. – SevenBits

1

클래스 메서드는 C++의 정적 메서드와 가장 유사합니다. 그러나 그들은 동일하지 않습니다. C++ 클래스는 런타임에 존재하지 않습니다. Objective-C의 클래스는 메소드를 호출 할 수있는 실제 객체입니다 (Objective-C 언어에서 메시지를 보냅니다). 그래서 목표 - C에서이 같은 물건을 수행 할 수 있습니다 일을 유사하다

Class classObj = [NSString class]; 
NSString *instanceObj = [classObj stringWithFormat:@"Hi I am %d years old", 36]; 

는 :

NSString *instanceObj = [NSString stringWithFormat:@"Hi I am %d years old", 36]; 

당신은 잘 무료로 당신에게 Factory pattern을 제공, 그 목적이 무엇인지 궁금 할 것이다 . 예 : 이 클래스를 사용하여 플러그인 클래스와로드 된 클래스의 호출 클래스 메소드를 어떤 클래스인지 모르게로드합니다.

귀하의 본보기와 관련하여. 오브젝티브 C에서 하나는 일반적으로 너무 초기화에서 할당을 분리 :

Deck *deckWithCards = [Deck newDeck:52]; 

권장 하지입니다. 대신 다음과 같이 작성해야합니다.

Deck *deckWithCards = [[Deck alloc] initWithNoCards:52]; 

원래 질문에 대한 설명은 생성자와 동일한 클래스 메소드입니다. 내가봤을 때, 그들은 왜 겹쳐 쓰는 사용법을 가지고 있기 때문에 당신이 비교를하는지 이해할 수는 있지만 실제로는 그렇지 않습니다.

그러나 실제로 Objective-C에는 생성자와 같은 것이 없습니다. C++ 및 Java의 생성자는 언어의 일부이며 매우 구체적인 용도로 사용됩니다. C++ 및 Java에서 생성자를 호출하지 않고는 객체를 만들 수 없습니다. Objective-C에서 이것은 언어에 고정되어 있지 않습니다. 모든 것이 대회에 관한 것입니다. allocinit은 단지 규칙입니다. 마찬가지로 클래스 메소드를 사용하여 모든 작업을 수행 할 수 있습니다. 그들은 어떤 객체도 만들 필요가 없습니다.

자세한 내용은 Mike Ash's article about how you can implement NSObject을 권장합니다.

+0

링크 된 기사는 좋지만 정적 메서드를 이해하려고하는 사람에게는 너무 복잡합니다. – SevenBits

+0

@SevenBits 네, 그럴 가능성이 너무 많습니다. 그러나 나는 그것이 사람에 달려 있다고 생각합니다. 빠른 대답은 도움이되지 않습니다. 그러나 정적 메서드가 개체 생성의 컨텍스트에서 클래스 메서드와 다른 이유를 실제로 이해하려는 사람에게는 매우 유용 할 수 있습니다. –