'정적 기능'은 언제 사용됩니까?


24

좋아, 정적 함수가 무엇인지 배웠지 만 여전히 개인 함수보다 왜 유용한 지 알 수 없습니다. 이것은 일종의 새로운 질문 일 수 있지만 왜 모든 개인 멤버 함수를 정적 함수로 대체하지 않습니까?


1
"정적 함수를 모두 전용 멤버 함수로 교체"해서는 안됩니까? 현재 정적 메소드의 요점을 보지 않고 왜 더 많은 메소드를 사용하지 않는지 묻습니다.

5
"정적 기능"이란 무엇입니까? C ++에서 적어도 두 가지 의미 (그리고 C ++ 11 초안 보았다 마지막으로 나는 거기에, 그들은을 위해 사용되지 않는다는 알림을 제거했던 static파일 범위에 기능을 제한.
데이빗 쏜리

C / C ++의 파일 범위 정적 자유 함수 또는 "정적 memenber 함수 / 방법"이라는 의미에서 "정적 함수"를 의미합니까? 큰 차이가 있습니다!
Jan Hudec

@ JanHudec : private memberOP가 OO 개념을 요구하고 파일 범위 정적에 대한 단서가 없다고 가정 할 수 있다고 생각합니다.
Matthieu M.

@MatthieuM .: 실제로 '개인 멤버'의 존재는 정확히 그가 C ++ 의미에서 정적 함수를 의미한다고 믿게합니다. 파일 범위 정적 함수와 개인 멤버 함수는 C ++에서 매우 유사한 두 가지 기능이므로 공용 정적 멤버를 비공개 비 정적 멤버로 바꾸는 것은 의미가 없습니다. 불행히도 OP는 응답하지 않는 것 같습니다.
Jan Hudec

답변:


24

OOP 를 사용 한다고 가정하면 클래스 멤버에 의존하지 않는 정적 함수를 사용하십시오. 그것들은 여전히 ​​비공개 일 수 있지만, 이런 식으로 관련 객체의 인스턴스에 의존하지 않기 때문에 최적화됩니다.

위의 것 외에도 정적 함수는 하나의 공용 함수를 실행하기 위해 객체의 인스턴스를 만들고 싶지 않을 때 유용합니다. 이것은 반복적이고 일반적인 작업을 수행하기 위해 공용 함수를 포함하는 헬퍼 클래스의 경우에 주로 해당되지만 호출 사이에 상태를 유지할 필요는 없습니다.


Bernard 감사합니다. Btw, 컴파일러가 "메소드를 클래스에 바인딩"하는 것이 무엇을 의미하는지 알고 있습니까?
Dark Templar

@Dark Templar : 내가 할 말이 없습니다. 특정 언어에만 해당됩니까?
Bernard

나는 당신의 정의에 약간의 문제가있다. 멤버 정적 함수는 비 정적 멤버에 액세스 할 수 없지만 정적 멤버에 액세스 할 수 있습니다. 정적 멤버는 클래스의 멤버입니다.
newprint

@ newprint : 당신은 정확하지만, 내가 말한 것은 아닙니다. 나는 그들이 어떤 반원에게 의존하지 않을 말했다 . 필요한 경우 정적 멤버를 사용하는 것이 좋지만 항상 그런 것은 아닙니다.
Bernard

8

위의 것보다 더 간단한 설명을 시도합니다 (꽤 좋은 것).

객체는 일반적으로 코드 + 데이터입니다. 정적 메소드는 처리 할 "코드"부분 만있는 경우에 사용됩니다 (유지되는 데이터 / 상태가없는 경우 (정적 데이터 멤버 제외)).


5

인스턴스가 필요하지 않고 공개 될 수 있기 때문입니다. 가장 큰 공통 분모를 얻는 함수가 필요하다고 가정하십시오 (GCD; 분수 클래스에 매우 유용합니다; 예) 이것은 단순한 예입니다. 객체 클래스를 만들 때는 그 자체의 목적이 this필요없고 사용하지 않는 포인터를 가질 수 있다는 것 입니다 gcd. 따라서 실제로 GCD를 사용하는 클래스 (예 : 분수 클래스)에서 정적 메소드를 사용하십시오.

정적 메소드 만있는 경우에는 OOP를 잘못하고 실제로 OOP를 수행하거나 패러다임에 더 적합한 언어를 사용해야합니다.


무료 기능을 사용하는 것이 귀하의 예에서 더 좋지 않습니까?
Ela782

2
@ Ela782 언어에 무료 기능이 있으면 예.

안심 해 주셔서 감사합니다. 최근에이 모범 사례 만 배웠습니다. 그러나 현재 공용 정적 멤버 함수가 실제로 유용 할 수있는 시점을 보는 데 어려움을 겪고 있습니다 .C ++과 같은 언어로 가정 해 봅시다. 둘 다의 유스 케이스는 함수가 클래스의 인스턴스에 의존하지 않거나 필요하지 않은 경우입니다. 그런 다음 무료 함수가 권장됩니다. 아마도 이것은 새로운 질문이 될 것입니다.
Ela782

1
@ Ela782 네, 좋은 질문이 될 수 있습니다. 빠른 두 가지 요점 : C ++에서 정적 멤버는 네임 스페이스가 아닌 형식을 템플릿 매개 변수로 전달할 수 있으므로 템플릿 메타 프로그래밍에 유용합니다. 일반적으로 정적 함수는 네임 스페이스에 속한 것과는 반대로 함수가 실제로 일부 클래스에 밀접하게 속해 있음을 나타내는 데 사용할 수 있습니다 (think stuff::Thing::Load(...)vs stuff::LoadThing()).

2

나는 일반적인 작업에 대한 도우미 기능으로 사용합니다.

  • 도를 라디안으로 변환 (또는 그 반대로);
  • 문자열 해싱;
  • 열거 형에서 다른 것으로 변환 (이 프로젝트에서 나는 해시 테이블의 역할을합니다);

정적 함수를 그룹화하는 대부분의 파일에는 접미사 헬퍼가 있습니다. 즉, 수행하는 작업이므로 더 빨리 찾을 수 있습니다.


2

정적 방법은 무엇입니까?

정적 메소드는 클래스의 인스턴스가 필요하지 않으며 이러한 인스턴스의 데이터 (또는 이것, self, Me 등)에 내재적으로 액세스 할 수 없습니다. [ 1 ]

정적 메소드가 유용한 경우의 예 :

  • 글로벌 / 헬퍼 메소드
  • 데이터 모델 클래스에서 쿼리 결과 가져 오기 (SP 호출)

적절한 곳에만 사용하십시오.

  1. 여러 객체에서 동일한 메소드를 복사하는 것을 발견하면 메소드를 정적으로 작성하여 DRY를 수행하십시오.
  2. 객체의 인스턴스가 필요하지 않은 경우 정적 메소드를 사용하십시오 (작업과 객체의 인스턴스 변수를 수행하지 않음)

많은 데이터가 객체 외부에 있고 정적 메소드를 통해 작업하는 경우 코드는 객체 지향적이지 않으므로 유지 관리가 어려워 질 수 있습니다.


1

정적 및 개인은 실제로 직교합니다. 메소드는 정적이거나, 개인용이거나, 또는 전혀 또는 둘 다일 수 있습니다.

정적 대 비 정적 (일명 '인스턴스 메소드')은 메소드가 클래스 자체에서 작동하는지 (정적) 하나의 특정 인스턴스에서 (정적이지 않음) 나타냅니다. 언어에 따라 인스턴스를 통해 정적 메서드를 호출 할 수 있지만 정적 메서드를 통해 인스턴스에 액세스 할 수는 없습니다 (정적 메서드 내부에서 정적이 아닌 메서드를 호출 할 수 없음을 의미 함). this목적). 정적 메서드를 사용하여 개념적으로 클래스에 연결되지만 특정 인스턴스에 '바인딩'되지 않는 동작을 구현하십시오. 정적 메서드를 사용하려는 또 다른 시나리오는 클래스의 두 인스턴스에서 작동하는 함수가 있고 피연산자가 권한있는 상태를 가질 자격이없는 경우입니다 (예 : 클래스가 있다고 가정)Vector추가를 구현하려고합니다. 추가 방법을로 호출 할 수 a.Add(b)있지만 Vector.Add(a, b)아마도 더 의미가 있습니다.

비공개 대 공개는 방법의 가시성 에 관한 것입니다. 비공개 메소드는 클래스 자체 범위 내에서만 액세스 할 수 있으며 공개 메소드는 어디에서나 액세스 할 수 있습니다. 이를 위해 가장 중요한 용도는 캡슐화입니다. 코드의 나머지 부분에서 클래스와 통신하기 위해 반드시 필요한 메소드와 속성 만 공개함으로써 외부 코드가 문제를 일으킬 수있는 지점을 제한하고 내부 문제를 방지합니다. 학급에서 다른 프로젝트로 피가 흘렀습니다.

따라서 경험 법칙 :

  • 클래스 외부에서 호출해야하는 것을 제외한 모든 멤버 함수를 비공개로 설정
  • 클래스의 인스턴스가없는 경우에도 의미가없는 한 모든 메서드를 인스턴스 메서드로 만듭니다.

0

유틸리티 클래스, 인스턴스 데이터가없는 클래스, 유용한 관련 메소드 컬렉션을 묶는 한 가지 방법으로 C ++ 및 C #에서 정적 메소드를 사용합니다.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();

0

C ++에 대해 말하고 있고 말하지 않았으며 올바른 용어가 있다고 가정합니다 (즉, 멤버 함수 / 메소드를 의미하지 않음).

개인 멤버 함수조차도 헤더에 선언해야하므로 사용자가 실제로 호출 할 수는 없지만 실제로 클래스의 API 및 ABI의 일부가됩니다. 개인 멤버 함수를 추가, 수정 또는 삭제하면 모든 종속 클래스를 다시 컴파일해야합니다 (헤더가 변경되어 더 잘 알 수 없음). 라이브러리에서 그렇게 할 때 응용 프로그램의 호환성을 고려해야합니다 그것.

반면에 파일 범위 정적 함수에는 공용 기호가 없으므로 원하는대로 추가, 수정 또는 삭제할 수 있으며 하나의 컴파일 단위를 넘어서는 영향을받지 않습니다.


0

일반적으로 프로그램의 진입 점으로 작동하려면 정적 주가 필요합니다. 그것은 중요 할 수 있습니다.


0

정적 함수 (및 다른 언어로 된 용어에 대해 다른 의미가 있음)는 호출간에 유지되는 상태를 요구하지 않습니다. 그것이 클래스가하는 것과 개념적으로 밀접하게 묶여 있다면, 그것을 클래스 함수 (오브젝트가 아닌 클래스에서와 같이)로 만들거나 그렇지 않으면 전역 (또는 모듈 수준의) 함수로 만드십시오. 객체 상태가 필요하지 않은 객체에는 속하지 않습니다.

상태를 항상 상태를 전달하는 경우 실제로 상태 비 저장 함수가 아닌 경우 상태 비 저장 구문을 사용하여 상태 저장 함수를 만드는 것입니다. 이 경우 아마도 호출 객체에 속하거나 상태와 동작을 더 잘 맞추기위한 리팩토링이 표시 될 수 있습니다.


0

"단지 모든 비공개 멤버 함수를 정적 함수로 바꾸지 않겠습니까?"

... 개인 멤버가 다른 멤버 함수 내에서 호출 한 경우에만 인스턴스 데이터에 액세스 할 수 있기 때문에. 정적 함수는 private 일 수 있지만 인스턴스가 매개 변수로 전달되지 않으면 클래스의 인스턴스를 변경하거나 참조 할 수 없습니다.


0

아무도 아직 좋은 대답을 할 수 없었던 방법이 재밌습니다. 나는 이것도 확실하지 않다. 당신은 아마도 그것들을 가능한 한 적게 사용해야한다는 힌트로 받아 들여야 할 것입니다. 그들은 결국 OOP보다는 절차 적입니다.

다음은 몇 가지 예입니다.

클래스 메소드라고하는 Obj-C에서는 일반적으로 객체가 반환되기 전에 참조 카운팅 풀에 배치되는 할당 래퍼로 사용됩니다.

Obj-C의 또 다른 예는 클래스 컬렉션에 새 클래스를 등록하는 것입니다. 각각 한 유형의 파일을 처리하는 클래스 세트가 있다고 가정 해 봅시다. 새 파일 형식에 대한 새 클래스를 만들면 파일 형식을 결정하는 클래스의 정적 메서드를 사용하여 컬렉션 (전역 변수)에 클래스를 등록 할 수 있습니다.

C ++에서 내가 생각할 수있는 또 다른 용도는 부드럽게 오류를 잡는 것입니다. 예외를 던지는 것 외에는 생성자 함수가 실패 할 수 없습니다. 오류 인스턴스 변수를 설정할 수 있지만 항상 적절한 것은 아닙니다. 대신 정적 랩퍼에서 실패한 파트를 수행 한 다음 새 오브젝트를 할당 및 리턴하거나 실패시 NULL을 수행 할 수 있습니다.


0

무언가의 부비동을 계산한다고 가정 해 봅시다.

정적없이 :

Math math = new Math()
double y = math.sin(x)

정적으로 :

double y = Math.sin(x)

sin비 정적 으로 만드는 것은 의미가 없습니다 . 상태가없고 입력 만 처리합니다.

정적 함수는 특정 객체에 연결되지 않습니다. 그것들은 객체의 내부 상태와 무관 한 "일반적인"기능입니다.


정적 메소드 "상태 비 저장"으로 보장 되지 않습니다 . 인스턴스 데이터를 사용할 수 없다는 것은 사실이지만 정적 상태, 즉 정적 메서드, 정적 메서드가 속한 클래스 및 다른 클래스의 정적 변수와 같은 다른 전역 적으로 보이는 상태에 대한 액세스 권한도 있습니다.

@ 델난 : 사실 ... 당신이 맞아요. 지금 바로 수정하겠습니다.
dagnelies

정적없이 : x.sin(). 당신의 대답은 죄가 "수학"의 기능이어야한다고 가정하지만, 그것은 분명히 이중에서 작동합니다.
AjahnCharles

0

여기서 늦었지만 정확한 정의를 작성하려고합니다. 정적 함수는 포함 클래스의 인스턴스 속성 / 메소드를 참조하지 않거나 참조 할 수없는 함수입니다.

C #과 같은 일부 언어에서는 정적 클래스에 정적 필드 또는 속성이있을 수 있으므로 상태에 사용되지 않는다고 말하는 것은 옳지 않습니다. 정적 함수는 정적 (전역) 상태를 사용할 수 있습니다.

기본적으로 다음과 같이 요약됩니다. 정적과 같은 정적 함수는 정적이 아닌 인스턴스에 종속되지 않고 항상 사용할 수있는 경우에 유용합니다.

수학 함수와 같은 도우미 함수는 자주 사용되는 예이지만 다른 함수도 있습니다.

생성하는 클래스에서 데이터를 변경할 수없는 경우 인스턴스를 변경할 수 없거나 변경해서는 안되는 인스턴스를 가져 와서 새 인스턴스를 전달하는 정적 함수를 만드는 것이 좋습니다. 예를 들어, 문자열 클래스는 문자열 (또는 2 이상)을 받아서 새 문자열을 다시 전달하는 정적 함수를 가질 수 있습니다.

또 다른 이유는 전역 상태 또는 어떤 종류의 데이터를 유지하는 클래스가 있기 때문일 수 있습니다. 해당 정적 클래스의 정적 속성 또는 필드와 함께 작동하는 정적 함수가있을 수 있습니다.


0

정적 f ()의 또 다른 사용을 지적하고 싶습니다.

http://www.parashift.com/c++-faq/named-ctor-idiom.html

static함수는 "명명 생성자"를 만들 수 있습니다. 즉, 적절한 자체 문서화 이름으로 정적 함수의 이름을 지정하면이 정적 함수는 생성자 중 하나를 호출합니다 (생성자는 이름이 동일하므로 그들 중 다수는 구분하기가 어렵습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.