명명 규칙-C ++ 및 C # 변수의 밑줄


146

_var클래스 필드에서 변수 이름 을 보는 것이 일반적 입니다. 밑줄은 무엇을 의미합니까? 이러한 모든 특수 명명 규칙에 대한 참조가 있습니까?



17
잘못 코딩 된 일부 회사 코딩 지침에서는 클래스와 함수가 필연적으로 너무 커져서 모호한 단서가없는 것을 추적 할 수 없다는 신념으로 인해 지역 변수와 구별하기 위해 구성원 변수에 사마귀를 추가 할 것을 제안합니다. 그러한 규칙을 제안하는 사람들은 코드가 가장 필요한 사람들입니다.
Mike Seymour

26
@Mike-담요 명세서는 사실이 아닙니다. 이 규칙을 사용하면 메소드를 빠르게 스캔하고 클래스를 잘 이해할 수 있습니다.
ChaosPandion

12
@ChaosPandion : 그런 다음 담요 명세서로 읽지 마십시오. "일부"는 "모두"를 의미하지 않으며 "너무 자주"는 "항상"을 의미하지 않으며 아마도 내 경험에서 예외 일 수도 있습니다.
Mike Seymour

17
C ++에서 피가 선도 밑줄. 많은 맥락에서 (즉, 글로벌 범위에서 대문자가 뒤 따르는 경우 등) 구현 용으로 예약되어 있으며 실제로는 매크로에 대한 매크로 트램 플이 발생할 위험이 있습니다. 따라서 원하는 경우 밑줄로 표시하십시오 .
sbi

답변:


120

밑줄은 단순히 규칙입니다. 더 이상 없습니다. 따라서 그 사용은 항상 사람마다 다소 다릅니다. 문제의 두 언어에 대해 이해하는 방법은 다음과 같습니다.

C ++에서 밑줄은 일반적으로 개인 멤버 변수를 나타냅니다.

C #에서는 일반적으로 공용 속성에 기본 개인 멤버 변수를 정의 할 때만 사용됩니다. 다른 개인 멤버 변수에는 밑줄이 없습니다. 이 사용법은 자동 속성의 출현으로 대체로 길을 갔다.

전에:

private string _name;
public string Name
{
    get { return this._name; }
    set { this._name = value; }
}

후:

public string Name { get; set; }

11
속성을 변경할 수없는 팀을 제외하고.
ChaosPandion

11
밑줄로 시작하는 식별자는 컴파일러 용으로 예약되어 있습니다. 접두사 밑줄을 사용하면 컴파일러 기호와 충돌 할 수 있습니다 .
Thomas Matthews

12
@Thomas Matthews-C #에는 없습니다.
EMP

11
@ChaosPandion "불변"이라는 말의 의미가 실제로 "읽기 전용"인 것으로 가정하고 있습니다 public string Name { get; private set; }. 사실, 그것은 불변의 것이 아니지만 거기에 있습니다.
jdmichal

7
@Thomas 클래스 컨텍스트에서 밑줄로 시작하는 식별자, C ++로 예약 된 대문자가 뒤 따릅니다 . _var예약되지 않았습니다.
Tyler McHenry 1

84

C ++에서 변수 이름 또는 매개 변수 이름 앞에 UNDERSCORES를 사용하지 않는 것이 좋습니다.

밑줄 또는 이중 밑줄로 시작하는 이름은 C ++ 구현자를 위해 예약됩니다. 밑줄이있는 이름은 라이브러리가 작동하도록 예약되어 있습니다.

C ++ 코딩 표준을 읽으면 첫 페이지에 다음과 같이 표시됩니다.

"명명을 과대 평가하지 말고 일관된 명명 규칙을 사용하십시오. 두 가지 필수 사항 만 있습니다. (p2, C ++ 코딩 표준, 허브 셔터 및 Andrei Alexandrescu)

보다 구체적으로, ISO 실무 초안 에는 실제 규칙이 나와 있습니다.

또한 일부 식별자는 C ++ 구현에서 사용하도록 예약되어 있으며 다른 방식으로 사용해서는 안됩니다. 진단이 필요하지 않습니다. (a) 이중 밑줄 __을 포함하거나 밑줄로 시작하고 대문자로 시작하는 각 식별자는 모든 사용을 위해 구현에 예약되어 있습니다. (b) 밑줄로 시작하는 각 식별자는 전역 네임 스페이스에서 이름으로 사용하기 위해 구현에 예약되어 있습니다.

실수로 위의 제한 중 하나에 빠질 경우 밑줄로 기호를 시작하지 않는 것이 가장 좋습니다.

소프트웨어를 개발할 때 이러한 밑줄을 사용하는 것이 왜 비참한 지 스스로 알 수 있습니다.

다음과 같이 간단한 helloWorld.cpp 프로그램을 컴파일하십시오.

g++ -E helloWorld.cpp

백그라운드에서 발생하는 모든 것을 볼 수 있습니다. 다음은 스 니펫입니다.

   ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
   try
     {
       __streambuf_type* __sb = this->rdbuf();
       if (__sb)
  {
    if (__sb->pubsync() == -1)
      __err |= ios_base::badbit;
    else
      __ret = 0;
  }

이중 밑줄로 시작하는 이름의 수를 볼 수 있습니다!

또한 가상 멤버 함수를 보면 * _vptr은 클래스에서 하나 이상의 가상 멤버 함수를 사용할 때 자동으로 생성되는 가상 테이블에 대해 생성 된 포인터임을 알 수 있습니다! 그러나 그것은 또 다른 이야기입니다 ...

밑줄을 사용하면 충돌 문제가 발생할 수 있으며 너무 늦을 때까지 그 원인을 파악할 수 없습니다.


4
전역 또는 파일 범위가 아니며 밑줄과 소문자로 시작하는 이름이 완벽하지 않습니까? 특정 경우에 매우 깨끗하기 때문에 항상 이렇게합니다. void A :: set_size (int _size) {size = _size; }. 이처럼 사소한 용도로는 어떻게해야합니까?
tukra

3
내가 생각하는 비전 역 / 파일 범위에서는 밑줄과 소문자가 허용됩니다. 표준에서 그렇지 않은 곳을 보여줄 수 있습니까? 밑줄 뒤의 문제는 이미 멤버 변수에 이미 사용한다는 것입니다. 따라서 함수 'int size ();'가있을 수 있습니다. 멤버 var 'int size_;' 인수 'int _size'. 이것은 잘 다루는 경향이 있으며 더 나은 대안을 보지 못했습니다. STL과 함께 작동하는 제네릭에는 대문자로 된 기능을 사용할 수 없습니다. C # 사람들이 좋아하는 'this.size'스타일은 항상 추악한 멤버 액세스에 사용하지 않으면 오류가 발생하기 쉽습니다.
tukra

7
합법적 인 내용을 명확하게 유지하는 데 어려움이있을 수 있으므로 밑줄과 소문자를 사용하지 않으려는 사람들도 있습니다. C ++ 표준은 일부 작성자가이를 사용하지 않는 것이 좋습니다. 나에게는 그것이 완전히 합법적이고 예약되지 않았기 때문에 위험하다고 생각할 이유가 없습니다. 의견을 보내 주셔서 감사합니다.
tukra

3
@tukra : 완전히 합법적 이지 않습니다 . C ++ 표준 은 단일 범위 밑줄과 로컬 범위에서 소문자 사용할 수 있습니다. 행운을 빕니다! :-)
Constantinos Glynos

4
죄송합니다. 자격을 되풀이해야한다고 생각했습니다. 밑줄로 시작하고 그 뒤에 소문자가 오는 C ++ 식별자는 파일 범위 이외의 모든 범위에서 허용됩니다. 함수, 함수 프로토 타입, 클래스, 구조체, 공용체, 열거 형 및 네임 스페이스에 넣는 모든 것에서 안전하고 합법적입니다. 네임 스페이스에 모든 코드를 넣는 일반적인 관례를 따르면 완전히 안전합니다.
tukra

45

실제로이 _var규칙은 C #이나 C ++가 아닌 VB에서 나옵니다 (m _, ...는 또 다른 것입니다).

이는 속성을 선언 할 때 VB의 대 / 소문자 구분을 극복했습니다.

예를 들어, 이러한 코드는 고려되기 때문 VB에서 불가능 userUser동일한 식별자

Private user As String

Public Property User As String
  Get
    Return user
  End Get
  Set(ByVal Value As String)
    user = value
  End Set
End Property

이를 극복하기 위해 일부 사람들은 '_'을 개인 필드에 추가하여 다음과 같이 표시했습니다.

Private _user As String

Public Property User As String
  Get
    Return _user
  End Get
  Set(ByVal Value As String)
    _user = value
  End Set
End Property

많은 규칙이 .Net에 대한 것이며 C #과 VB.NET 규칙간에 균일 성을 유지하기 위해 동일한 규칙을 사용하고 있습니다.

내가 말한 것에 대한 참조를 찾았습니다 : http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

밑줄이있는 낙타 케이스. VB.NET에서 항상 "Protected"또는 "Private"를 표시하고 "Dim"을 사용하지 마십시오. "m_"의 사용은 권장되지 않는 보호 된 변수의 경우에만 속성과 다른 경우에만 속성과 다른 변수 이름을 사용하지 않는 것이 좋습니다. VB.NET에서 프로그램을 프로그래밍 할 때 삶을 고통스럽게 할 수 있습니다. 접근 자 / 돌연변이 속성과 다른 이름을 멤버에 지정해야합니다. 여기에있는 모든 항목 중 주요 밑줄은 실제로 유일한 논란입니다. 개인적으로 변수에 밑줄이없는 낙타보다 선호하기 때문에 변수 이름을 "this"로 한정 할 필요가 없습니다. 이름 충돌이 발생할 가능성이있는 생성자 또는 다른 곳의 매개 변수와 구별하기 위해. VB.NET의 대소 문자를 구분하지 않으면 접근 자 속성의 이름이 밑줄을 제외하고 개인 멤버 변수와 같은 이름을 가지므로 더욱 중요합니다. m_가가는 한, 그것은 실제로 미학에 관한 것입니다. 변수 이름에 구멍이있는 것처럼 보이기 때문에 나 (그리고 다른 많은 사람들)는 m_ ugly를 찾습니다. 거의 모욕적입니다. 나는 항상 VB6에서 그것을 사용했지만 변수는 선행 밑줄을 가질 수 없었기 때문입니다. 나는 그것이 사라지는 것을보고 더 행복 할 수 없었다. 코드에서 두 가지를 모두 수행했지만 m_ (및 직선 _)을 사용하지 않는 것이 좋습니다. 또한, "m"으로 시작하는 접두사도 있습니다. 물론 이들은 주로 C #으로 코딩되므로 속성과 경우에만 다른 개인 멤버를 가질 수 있습니다. VB 사람들은 다른 일을해야합니다. 언어 별 특수한 경우를 시도하기보다는이를 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 지원할 모든 언어에 대해 밑줄을 사용하는 것이 좋습니다. 클래스가 CLS를 완전히 준수하도록하려면 C # 보호 멤버 변수의 접두사를 생략 할 수 있습니다. 그러나 실제로 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. . 잠재적으로 보호되는 모든 멤버 변수를 비공개로 유지하고 대신 보호 된 접근 자와 뮤 테이터를 제공하므로 걱정할 필요가 없습니다. 이유 : 간단히 말해서,이 규칙은 간단하고 (한 문자), 읽기 쉬우 며 (눈이 다른 주요 문자에 방해가되지 않음) 절차 수준 변수 및 클래스 수준 속성과의 이름 충돌을 성공적으로 피할 수 있습니다. .


6

첫 번째 주석 자 (R Samuel Klatchko) 는 다음과 같이 언급했습니다. C ++ 식별자에 밑줄을 사용하는 것에 대한 규칙은 무엇입니까? C ++의 밑줄에 대한 질문에 대답합니다. 일반적으로 컴파일러의 구현자를 위해 예약되어 있으므로 밑줄을 사용하지 않아야합니다. 당신이보고있는 코드 _var는 아마도 레거시 코드이거나 오래된 밑줄을 찌르지 않는 오래된 명명 시스템을 사용하여 자란 누군가가 작성한 코드 일 것입니다.

다른 답변 상태로, 클래스 멤버 변수를 식별하기 위해 C ++에서 사용되었습니다. 그러나 데코레이터 나 구문이 사용되는 한 특별한 의미는 없습니다. 그래서 당신이 그것을 사용하려면 컴파일됩니다.

C # 토론을 다른 사람에게 맡기겠습니다.


5

_var은 의미가 없으며 변수가 전용 멤버 변수임을 쉽게 구별 할 수 있도록하는 목적으로 만 사용됩니다.

C ++에서는 식별자 앞에 밑줄 사용을 제어하는 ​​규칙이 있기 때문에 _var 규칙을 사용하는 것은 잘못된 형식입니다. _var은 전역 식별자로 예약되어 있으며 _Var (밑줄 + 대문자)은 언제든지 예약되어 있습니다. 이것이 C ++에서 var_ 규칙을 대신 사용하는 사람들을 보는 이유입니다.


4

고유 한 코딩 지침을 만들 수 있습니다. 나머지 팀을 위해 명확한 문서를 작성하십시오.

_field를 사용하면 Intelilsense에서 _ 만 입력하면 모든 클래스 변수를 필터링 할 수 있습니다.

나는 보통 Brad Adams Guidelines 를 따르지만 밑줄을 사용하지 않는 것이 좋습니다.


2

C #의 Microsoft 명명 표준에 따르면 변수와 매개 변수는 소문자 낙타 경우 IE :를 사용해야합니다 paramName. 필드가 같은 양식을 할 수 있지만, 많은 팀이 명확하게 개선하기 위해 밑줄 접두사를 요구 있도록이 불분명 코드로 이어질 수에 대한 표준도 호출 IE를 : _fieldName .


2

C #에서 Microsoft Framework Design Guidelines공용 멤버에 밑줄 문자를 사용하지 않는 것이 좋습니다 . 내용은 개인 회원, 밑줄은 사용하기 OK입니다. 실제로 Jeffrey Richter (가이드 라인에 종종 언급 됨)는 m_를 사용하고 개인 정적 멤버는 "s_"를 사용합니다.

개인적으로 저는 _를 사용하여 개인 회원을 표시합니다. "m_"및 "s_"는 헝가리어 표기법에 따라 .NET에서 찌그러 질뿐만 아니라 매우 장황 할 수 있으며 많은 구성원이있는 클래스를 알파벳순으로 빠른 시선 검사를하기가 어렵습니다 (모두 10 개의 변수가 m_로 시작한다고 상상해보십시오) .


헝가리어 표기법은 유형을 나타내므로 실제로 m / s가 그것에 해당한다고 말할 수는 없습니다.
Jerry Nixon 4:20에

@ JerryNixon-MSFT 헝가리어 개념과 관련하여 변수 데이터 유형과 변수 가시성 유형을 동일한 것으로 식별합니까?
Necro

1

클래스의 멤버 변수에 _var 이름을 사용합니다. 내가하는 두 가지 주요 이유가 있습니다.

1) 나중에 코드를 읽을 때 클래스 변수와 로컬 함수 변수를 추적하는 데 도움이됩니다.

2) 클래스 변수를 찾을 때 Intellisense (또는 다른 코드 완성 시스템)에서 도움이됩니다. 첫 번째 문자 만 아는 것이 사용 가능한 변수 및 메소드 목록을 필터링하는 데 도움이됩니다.


1
큰 방법으로 호버 인텔리전스 또는 스캔을 사용하여 var가 로컬로 정의되어 있는지 여부를 확인하는 것이 번거 롭습니다. 언급 한 것과 같은 이유로 정적에 대해 "__"을 선호하지만 현재 선호하지 않습니다.
crokusek

1

C 및 C ++ 언어와 관련하여 이름의 밑줄 (시작, 중간 또는 끝)에는 특별한 의미가 없습니다. 유효한 변수 이름 문자 일뿐입니다. "컨벤션"은 코딩 커뮤니티 내의 코딩 관행에서 비롯됩니다.

위에서 다양한 예에서 이미 언급했듯이 처음에 _은 C ++에서 클래스의 개인 또는 보호 멤버를 의미 할 수 있습니다.

재미있는 사소한 역사를 알려 드리겠습니다. UNIX에서 코어 C 라이브러리 함수와 커널 함수를 사용자 공간에 노출하려는 커널 백엔드가있는 경우 _는 다른 작업을 수행하지 않고 커널 함수를 직접 호출하는 함수 스텁 앞에 붙어 있습니다. 가장 유명하고 친숙한 예는 BSD 및 SysV 유형 커널에서 exit () vs _exit ()입니다. 여기서 exit ()는 커널의 종료 서비스를 호출하기 전에 사용자 공간 작업을 수행하지만 _exit은 커널의 종료 서비스에 매핑됩니다.

따라서 _는 "로컬"항목에 사용되었으며이 경우 로컬은 로컬 머신입니다. 일반적으로 _functions ()는 이식성이 없었습니다. 다양한 플랫폼에서 동일한 동작을 기 대해서는 안됩니다.

이제 변수 이름에서 _와 같은

int _foo;

심리적으로, _는 처음에 입력해야하는 이상한 일입니다. 따라서 다른 프로세서와 충돌 할 가능성이 적은 변수 이름을 만들려는 경우, 특히 전 처리기 대체를 처리 할 때 _의 사용을 고려하십시오.

저의 기본 조언은 코딩 커뮤니티의 컨벤션을 항상 준수하여보다 효과적으로 협업 할 수 있도록하는 것입니다.


0

그것은 단순히 클래스의 멤버 필드임을 의미합니다.


0

특별한 단일 명명 규칙은 없지만 개인 회원에게도 나타났습니다.


0

많은 사람들이 개인 필드에 밑줄이 붙는 것을 좋아합니다. 그것은 단지 명명 규칙입니다.

C #의 '공식'명명 규칙은 개인 필드에 간단한 소문자 이름 (밑줄 없음)을 규정합니다.

밑줄이 매우 널리 사용되지만 C ++에 대한 표준 규칙을 알지 못합니다.


0

클래스의 멤버 또는 다른 종류의 변수 (매개 변수, 함수의 로컬 등)를 조작 할 때 명확하게하기 위해 일부 프로그래머가 사용하는 규칙 일뿐입니다. 멤버 변수에도 널리 사용되는 또 다른 규칙은 이름 앞에 'm_'을 붙입니다.

어쨌든 이것들은 관습 일 뿐이며 모든 것을위한 단일 소스를 찾을 수는 없습니다. 그것들은 스타일의 문제이며 각 프로그래밍 팀, 프로젝트 또는 회사에는 고유 한 것이 있습니다 (또는 아무 것도 없습니다).


0

VB.NET에서 코드를 확장 할 수 있어야하는 경우 C # 에서 코드 를 사용해야하는 합법적 인 이유가 있습니다 . (그렇지 않으면 안됩니다.)

VB.NET은 대소 문자를 구분하지 않으므로이 field코드에서 보호 된 멤버에 액세스하는 간단한 방법은 없습니다 .

public class CSharpClass
{
    protected int field;
    public int Field { get { return field; } }
}

예를 들어 필드가 아닌 속성 getter에 액세스합니다.

Public Class VBClass
    Inherits CSharpClass

    Function Test() As Integer
        Return Field
    End Function

End Class

도대체 field소문자로 도 쓸 수 없습니다. VS 2010은 계속 수정합니다.

VB.NET에서 파생 클래스에 쉽게 액세스 할 수 있으려면 다른 명명 규칙이 필요합니다. 밑줄 접두어는 아마도 가장 덜 침입적이고 가장 "역사적으로 받아 들여지는"것입니다.


0

이제 this.foobarbaz에서와 같이 "this"를 사용하는 표기법은 C # 클래스 멤버 변수에 허용됩니다. 이전 "m_"또는 "__"표기법을 대체합니다. 참조 대상이 무엇인지 의심하기 때문에 코드를 더 읽기 쉽게 만듭니다.


0

내 경험 (확실히 제한됨)에서 밑줄은 그것이 개인 멤버 변수임을 나타냅니다. 골룸이 말했듯이 이것은 팀에 달려 있습니다.


0

오래된 질문, 새로운 답변 (C #).

C #에 밑줄을 사용하는 또 다른 용도는 ASP NET Core의 DI (종속성 주입)입니다. readonly구성하는 동안 주입 된 인터페이스에 지정된 클래스의 개인 변수는 밑줄로 시작해야합니다. 클래스의 모든 개인 멤버에 대해 밑줄을 사용할지 여부는 논쟁의 여지가 있지만 (Microsoft 자체가 따르더라도) 확실합니다.

private readonly ILogger<MyDependency> _logger;

public MyDependency(ILogger<MyDependency> logger)
{
    _logger = logger;
}

-2

이와 같은 이름 지정 규칙은 코드, 특히 자신이 아닌 코드를 읽을 때 유용합니다. 강력한 이름 지정 규칙은 특정 멤버가 정의 된 위치, 멤버의 종류 등을 나타내는 데 도움이됩니다. 대부분의 개발 팀은 간단한 이름 지정 규칙을 채택하고 멤버 필드 앞에 밑줄 ( _fieldName)을 붙 입니다. 과거에는 C #에 대해 다음 이름 지정 규칙을 사용했습니다 (Reflector에서 볼 수있는 .NET 프레임 워크 코드에 대한 Microsoft의 규칙을 기반으로 함).

인스턴스 필드 : m_fieldName
정적 필드 : s_fieldName
퍼블릭 / 보호 / 내부 멤버 : PascalCasedName ()
프라이빗 멤버 : camelCasedName ()

이를 통해 사람들은 익숙하지 않은 코드를 매우 빠르게 읽을 때 구성원의 구조, 사용, 접근성 및 위치를 이해할 수 있습니다.


3
실제로 Microsoft는 m_, s_ 접두사를 사용하지 않는 것이 좋습니다. 필드 이름에 접두사를 사용하지 마십시오. 예를 들어, 정적 필드와 비 정적 필드를 구별하기 위해 g_ 또는 s_를 사용하지 마십시오. msdn.microsoft.com/ko-kr/library/ms229012.aspx
Zied

1
내가 말했듯이 Reflector로 소스 코드를 살펴보십시오. 그들이 자신의 추천을 얼마나 많이 숨기고 있는지 놀랄 것입니다. ;) 내 게시물에서 언급했듯이 코드의 가독성을 향상시키는 데 도움이되며 마지막 팀은 위에 나열된 명명 규칙을 정말로 좋아했습니다.
jrista
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.