2010-12-17 3 views
32

하나의 (기본값이 아닌) 매개 변수를 가진 생성자는 암시 적 변환기처럼 작동하여 해당 매개 변수 유형을 클래스 유형으로 변환한다는 점을 알고 있습니다. 그러나 explicit은 매개 변수가없는 생성자 (기본 생성자) 또는 둘 이상의 (기본값이 아닌) 매개 변수가있는 생성자를 한정하는 데 사용할 수 있습니다.둘 이상의 (기본값이 아닌) 매개 변수가있는 기본 생성자 및 생성자에 명시 적으로 허용되는 이유는 무엇입니까?

왜 이러한 생성자에 명시 적으로 허용됩니까? 어떤 종류의 암시 적 변환을 막는 데 유용한 예제가 있습니까?

+0

이 왜 방지해야 하는가? – Falmarri

+0

Falmarri : 예방되지 않으면 기본 생성자 또는> = 2 매개 변수 생성자에서 유용 할 수있는 예제가 있습니까? –

+0

Adrian의 답변을 참조하십시오. 왜 그것을 막아야합니까? – Falmarri

답변

7

아마도 이것은 단지 편의 일뿐입니다. dis- 할 이유가 없으므로 코드 생성기 등에서 삶을 힘들게 만드는 이유는 무엇입니까? 선택했다면 코드 생성 루틴은 생성되는 생성자의 매개 변수 수를 확인하는 추가 단계가 있어야합니다.

varioussources에 따르면 정확히 하나의 인수로는 호출 할 수없는 생성자에 적용 할 때 아무런 영향을 미치지 않습니다.

+1

"정확히 하나의 매개 변수없이"다시 말하면 정확히 하나의 인수로는 호출 할 수없는 생성자에 적용 할 때 아무런 영향을 미치지 않습니다. 차이점이 있습니다. ;-) –

+0

미묘한 구별이지만 괜찮아 :) 고정. –

7

아마도 유지 관리를 지원하는 것이 었습니다. 복수 인수 생성자에 explicit을 사용하면 인수를 기본값에 추가 할 때 의도하지 않게 암시 적 변환이 발생하는 것을 피할 수 있습니다. 나는 그것을 믿지 않지만; 대신에, C++에서 많은 것들이 허용된다고 생각합니다. 언어 정의를 이미 복잡한 것보다 더 복잡하게 만들지 않기 만하면됩니다.

아마도 가장 악명 높은 사례가 로컬 변수가 아닌 static에 대한 참조를 반환하는 것일 수 있습니다. "무의미한"모든 것을 배제하고 다른 어떤 것도 영향을 미치지 않으면 서 추가적인 복잡한 규칙이 필요합니다. 그래서 그것은 단지 허용됩니다, 당신은 그 참조를 사용하면 UB 항복.

또는 생성자의 경우 기본 생성자를 여러 개 정의 할 수 있습니다. 그러나 서명 생성자가 다르면 둘 이상의 생성자를 기본적으로 호출하는 것이 어렵습니다. :-)

더 나은 질문은 아마 explicit도 변환 연산자에 허용되지 않습니다?

글쎄, C++ 0x 일 것입니다. 그래서 좋은 이유가 없었습니다. 전환 사업자에게 explicit을 허용하지 않는 실제 이유는 감독으로서의 황당하거나, 처음에 explicit을 채택하기위한 투쟁이거나,위원회 시간의 간단한 우선 순위 또는 기타와 같은 것일 수 있습니다.

건배 & HTH.,

4

당신이 유형 변환에 부수적으로 사용을 피하는명시 적모든 sinlge 매개 변수 생성자를 선언해야 표준를 코딩 높은 무결성 C++에 따르면. 확실히

class C { 
    public: 
    C(const C&); // ok copy 
    constructor C(); // ok default constructor 
    C(int, int); // ok more than one non-default argument 

    explicit C(int); // prefer 
    C(double); // avoid 
    C(float f, int i=0); // avoid, implicit conversion constructor 
    C(int i=0, float f=0.0); // avoid, default constructor, but 
           // also a conversion constructor 
}; 
void bar(C const &); 
void foo() 
{ 
    bar(10); // compile error must be 'bar(C(10))' 
    bar(0.0); // implicit conversion to C 
} 
35

한 가지 이유 : 경우에 여러 인자 생성자는 또한 몇 가지 기본 생성자의 종류에 변환 생성자를 생성자를 변환, 각자가 기본값이 여러 parametres을 받아들이는 생성자가 있다고 가정한다 다 치지 않기 때문입니다.

첫 번째 매개 변수에 대한 기본 인수가있는 경우 필요한 이유 중 하나입니다.생성자 컨스트럭터 지지만, 여전히

struct A { 
    explicit A(int = 0); // added it to a default constructor 
}; 

C++ 0X 다중 파라미터 생성자를위한 그것의 실제 사용한다 생성자

변환으로서 사용될 수있다. C++ 0x에서 이니셜 라이저 목록을 사용하여 클래스 객체를 초기화 할 수 있습니다. 당신이 = { ... }를 사용하는 경우 철학은 다음 개념적 개체의 추상적 인 값을 나타냅니다 "복합 값"의 일종으로 객체를 초기화하고, 당신이 형식으로 변환 한 것인지,

  • 입니다.

  • { ... } 이니셜 라이저를 사용하는 경우 반드시 개체 생성자를 직접 호출해야하며 변환을 지정하지 않아도됩니다.

이 예제이 방법으로

struct String { 
    // this is a non-converting constructor 
    explicit A(int initialLength, int capacity); 
}; 

struct Address { 
    // converting constructor 
    Address(string name, string street, string city); 
}; 

String s = { 10, 15 }; // error! 
String s1{10, 15}; // fine 

Address a = { "litb", "nerdsway", "frankfurt" }; // fine 

을 고려, C + +0는 C++ 03의 결정은 다른 생성자에 명시 적으로 허용하는 것을 보여준다는 전혀 나쁜 생각하지 않았다 .

+0

그래서 다중 매개 변수 생성자의'explicit'은 복사 생성자에서'explicit'과 비슷한 결과를줍니다. –

+1

@James는 하나의 인수로 호출 가능한 생성자에서 명시 적으로 비슷합니다 :) 그러나 목록 초기화의 차이점은 여전히 ​​명시 적 생성자를 고려한다는 것입니다. 선택하면 진단이 실행됩니다. 명백한 생성자를 그냥 무시하고, 비표 시적 생성자를 선호 할 가능성이있는'T t = v'와는 달리,위원회가 나쁜 것으로 생각한 것입니다. –

+0

오. 예. 바보 나. –

0

필자는 필연적으로 의미가없는 것을 허용하는 것이 모든 복잡성을 추가하는 것보다 더 간단하다는 데 동의합니다.

토론의 목적으로 만 사용하십시오. 나는 C++에 대한 지식이별로 없기 때문에 C++ 표준화위원회에서 암시 적 키워드를 고려하고 있는지 궁금해합니다. 이는 명시 적으로는 반대가되고 암시적인 유형 변환을 기본값이 아니게 만듭니다. 키워드없이

class SomeClass 
{ 
public: 
    implicit SomeClass(int i); 
}; 

, 다음이 가능하지 않을 것이다 :

SomeClass foo = 6; 

겠습니까 C가 완전히 이런 식으로 가고 다른 대신 명시 적으로 뭔가 ++?

암시가 하나 개 이상의 인수를 ctors에 대한 허용 할 필요가있는 경우 이것은 물론 후속 질문에 우리를 이끌 것 ...

+0

이것은 좋은 아이디어이지만 모든 코드와의 하위 호환성을 확실히 깨뜨릴 것입니다 ... 지금은 옵션이 아닙니다. –

관련 문제