문제

나는 MS Visual C ++ 6.0에 따라 프로그램을 작성하고 있습니다 (예, 고대라는 것을 알고 있습니다. 업그레이드를 위해 할 수있는 일은 없습니다). 나는 정말 이상하다고 생각하는 행동을보고 있습니다. 다음과 같이 정의 된 두 개의 생성자가있는 클래스가 있습니다.

class MyClass
{
public:
    explicit MyClass(bool bAbsolute = true, bool bLocation = false) : m_bAbsolute(bAbsolute), m_bLocation(bLocation) { ; }
    MyClass(const RWCString& strPath, bool bLocation = false);

private:
    bool m_bAbsolute;
    bool m_bLocation;
};

이 클래스의 인스턴스를이 구문으로 인스턴스화 할 때 : MyClass("blah"), 첫 번째 생성자라고합니다. 보시다시피, 나는 추가했다 explicit 그것을하지 않을 것이라는 희망으로 그것에 대한 키워드 ... 주사위는 없습니다. 전환을 선호하는 것으로 보입니다 const char * 에게 bool 전환을 통해 RWCString, 여기에는 복사 생성자가 있습니다 const char *. 왜 그렇게합니까? 나는 이와 같은 두 가지 가능한 선택이 주어지면 그것이 모호하다고 말할 것입니다. 이 작업을 수행하지 못하게하려면 어떻게해야합니까? 가능하다면, 나는 명시 적으로 캐스팅하지 않아도됩니다. strPath an에 대한 논쟁 RWCString, 그것은 리터럴과 함께 많이 사용될 것이므로 많은 추가 타이핑입니다 (정말 쉬운 실수).

도움이 되었습니까?

해결책

생성자가 암시 적 변환의 일부가 아니라 수신자에 불과하기 때문에 명시 적은 여기에서 도움이되지 않습니다.

선호하는 변환 순서를 제어 할 수있는 방법은 없지만 Const Char*를 취한 두 번째 생성자를 추가 할 수 있습니다. 예 :

class MyClass
{
public:
    MyClass(bool bAbsolute = true, bool bLocation = false);
    MyClass(const RWCString& strPath, bool bLocation = false);
    MyClass(const char* strPath, bool bLocation = false);

private:
    bool m_bAbsolute;
    bool m_bLocation;
};

다른 팁

Andrew Grant는 해결책을 제공했습니다. 말하고 싶어요 시도한 방식으로 작동하지 않습니다. 인수에 대한 두 가지 실행 가능한 기능이 있다면, 가장 인수와 일치하는 기능을 가장 많이 부릅니다. 두 번째는 사용자 정의 변환이 필요하지만 첫 번째는 표준 변환 만 필요합니다. 그렇기 때문에 컴파일러가 첫 번째를 두 번째로 선호하는 이유입니다.

당신이 계속 캐스팅하고 싶지 않다면, 당신은 const char*를 취하는 다른 ctor를 만들어야 할 것 같습니다.

그것이 내가이 상황에서 아마도 할 것입니다.

(왜 당신이 대부분의 사용을 통과하지 못하는 유형의 ctor를 만들고 있는지 잘 모르겠습니다.)

편집하다:

내가 내 입력하는 동안 다른 사람이 이미 게시 한 것을 봅니다.

왜 끈과 부울에 대한 언급을 혼동 해야하는지 잘 모르시겠습니까? 나는 bool과 int에 문제를 보았다.
첫 번째 생성자의 기본값을 잃을 수 있습니까? MyClass ()의 기본 생성자가되기 때문에 Args와 일치 할 수없는 경우 기본값도 가능합니다.

당신의 선택은 명시 적으로 const char *를 사용하는 생성자를 추가하는 것입니다 *

MyClass(const char* strPath, bool bLocation = false); // Thanks Andrew Grant!

또는

MyClass( string("blah") );

컴파일러는 본질적으로 const char *를 bool로 만드는 방법을 알고 있습니다. MyClass 생성자의 첫 번째 유형 유형의 MyClass 생성자에 대해 제공 한 소스 유형을 취할 수있는 생성자가 있는지 또는이를 수락 한 유형에 캐스팅 할 수 있는지 확인해야합니다. MyClass 생성자의 첫 번째 유형 유형의 생성자 또는 ... 글쎄, 당신은 이것이 어디로 가고 있는지 알 수 있으며 그것은 첫 번째 인수만을위한 것입니다. 그렇게하면 광기가 있습니다.

그만큼 explicit 키워드는 컴파일러에게 인수 유형의 값을 class의 객체로 변환 할 수 없다고 말합니다.

struct C { explicit C( int i ): m_i(i) {}; int m_i; };
C c = 10;//disallowed
C c( 2.5 ); // allowed

C ++에는 귀하의 경우에 어떤 생성자가 호출 될 것인지 결정하기위한 일련의 규칙이 있습니다. 머리 뒷면에서 알지 못하지만 기본 인수가 모호성으로 이어지는 것을 직관적으로 볼 수 있습니다.

당신은 그 불이행을 통해 생각해야합니다.

정적 인 건축 방법으로 떨어질 수 있습니다. 또는 다른 클래스 (디자인 관점에서 나쁜 선택이 아님)를 사용할 수 있습니다. 어느 쪽이든, 당신은 클라이언트 코드가 어떤 생성자를 사용할 것인지 결정하도록합니다.

struct C {
  static C fromString( const char* s, const bool b = true );
  static C fromBools( const bool abs = true, const bool b = true );
};

또는

struct CBase {
    bool absolute; 
    bool location;
    CBase( bool abs=true, bool loc=true );
};

struct CBaseFromPath {
    // makes 'absolute' true if path is absolute
    CBaseFromPath( const char* s, const bool loc );
};

당신은 확실한 그것이 실제로 첫 번째 생성자라고 부르는가? 당신은 끈으로 하드 코딩 된 문자열로 그것을 부르고 있습니까, 아니면 뒤에 숨겨져 있습니까? #define? #define이 당신이 생각하는 것인지 확신합니까? (확장 된 사전 처리기 출력을 얻으려면 /ef 옵션으로 컴파일하고 통화가 보이기를 기대하는지 확인하십시오.)

편집 :이 의견과 다른 의견을 바탕으로 저의 제안은 다른 생성자를 추가하는 것입니다. const char*. 그게 가능합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top