3

제목은 기본적으로 모두를 말합니다. 다른 API의 다른 함수의 매개 변수를 초기화 할 수있는 객체 (예 : 맞춤 문자열 객체)를 만들 수 있도록 주로이 작업을 수행하려고합니다. 다음 작업을 사용자 정의 정수 클래스를 얻으려고 나의 예 C++ 데이터 형식을 초기화 할 수있는 클래스를 어떻게 만듭니 까?

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    friend int &operator=(int &i, test t); 
}; 

int &operator=(int &i, test t) 
{ 
    return (i = t.member); 
} 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 

불행하게도 나는 그 연산자 = 멤버 함수 할 필요가 말하는 오류가 발생합니다. 할당 연산자에 대한 정적 및 비 멤버 오버로드가 구현되는 것을 막는 C++ 표준의 목표를 이해하고 있지만이를 수행 할 수있는 다른 방법이 있습니까? 어떤 도움이나 제안을 주셔서 감사합니다!

답변

3

뭘하려고 노력하는 것은 당신이 (단지 정수 멤버를 포함) 작성하려고하는 클래스에 대한 변환 연산자

operator int() 
{ 
    return this->member; 
} 

이 필요합니다, 당신은 과부하 할 필요가 없습니다 할 = 연산자.

= 연산자는 모든 클래스에 대해 기본적으로 컴파일러에서 생성되는 멤버 함수 중 하나입니다. 주의해야 할 점은 클래스 멤버의 비트 복사 (얕은 복사)는 간단한 것입니다. 정수 만 사용하면 충분하기 때문입니다.

이 경우 그 포인터의 얕은 사본이 동일한 동적 메모리 위치 &를 가리키는 멤버 포인터를 포함하는 모든 개체를 초래하기 때문에 동적, 멤버 함수로 포인터를 할당했다면 당신은 = 연산자를 오버로드해야합니다 오브젝트 중 하나가 수명이 끝나면 다른 오브젝트에는 매달린 포인터가 남아 있습니다.
@ 토니는 적절하게 의견을 지적합니다. 보통은 좋지만 이 아닌 것은 항상입니다. 시나리오에 대한 그의 의견을보십시오.

할당 연산자에 과부하를 걸려면 Copy and Swap Idiom을 올바르게 확인하십시오.

Rule of Three도 확인해야합니다.

+1

"[연산자 =] 피연산자의 비트 사본 (얕은 복사)에 의해 간단한 비트 않음"... 피연산자 ... 아마도 멤버 변수를 사용하는 이상한 용어? 그리고 그것들을 가지고있는 멤버들을 위해 복사 생성자를 호출합니다 - 비트별로 얕은 복사를하지 않을 수도 있습니다 (예를 들어'std :: string'). 위험한 포인터의 얕은 사본 : 일반적으로 사실이지만 항상 그런 것은 아닙니다 - 예 :(일반적으로'const') 정적 참조 데이터에 대한 포인터를 안전하게 복사 할 수 있습니다. –

+1

@ 토니 : 고마워! 필자는 회원들에게 피연산자에 대한 정보를 변경했다. 인정하지, 그렇게 장황하지 않았다. 동적 메모리 할당을 사용하는 멤버 포인터의 가장 일반적인 경우는 오버로드 된 기본 할당이 초보자를 가장 많이 상하게하기 때문입니다. 귀하의 의견은 답변을 읽는 사람에게 예외를 해독하는 데 도움이됩니다. 감사합니다. :) –

+1

예 - "newbies"가 "모든 포인터 = 자신의 연산자 = 필요"라고 생각할 수도 있습니다. 규칙. 그것은 좋은 지침이지만, 당신이 말한대로 초보자를 도와줍니다. 동적 메모리는 또 다른 위험 신호이지만 100 % 상관 관계는 없습니다. pointed-to 객체는'main()'에서 호출 된 팩토리 메소드에 의해 반환 될 수 있으며, 애플리케이션 종료 직전에 삭제되며, 객체를 가리키는 객체의 수명이 포함됩니다. 건배. –

5

이것은 할당 연산자가 있지만 오버로드 된 타입 변환이 포함되어 있지 않은 경우에 수행됩니다. 그러면 주 기능이 예상대로 작동합니다.

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 
    operator int() const {return member;} 
}; 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 
+2

+1,'operator int()'는'const'이어야하고'test (int)'는'explicit'이라면 더 안전합니다 ('test t = 90'). –

+0

@ 토니 : 힌트를 주셔서 감사합니다. – manol

+0

이것은 작동하는 것 같습니다! 고맙습니다! – AutoBotAM

1

할당 연산자는 friend 함수가 될 수 없습니다. 대입 연산자는 비 정적 멤버 함수로만 선언 할 수 있습니다. 이는 첫 번째 피연산자로 L 값을 받도록 보장하기위한 것입니다. [],() 및 -> 연산자에 대해서도 마찬가지입니다. 귀하의 경우, int는 빌드 인 (build-in) 유형이므로 멤버 함수를 사용할 수 없습니다. 연산자 int()를 구현하여 사용자 정의 유형을 int로 변환 할 수 있습니다.

+0

'int'에 비 정적 멤버 함수를 정의 할 수는 없습니까? – unkulunkulu

+0

@unkulunkulu, yup, int는 build-in 유형이기 때문에. 답변이 업데이트되었습니다. –

3

이 시도 :

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    operator int() {return this->member;} 
}; 

int main(void) 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 
관련 문제