현재 연산자가 오버로드 된 유틸리티 클래스를 만들고 있습니다. 회원 또는 비회원 (friend
) 기능을하는 데있어서 장단점은 무엇입니까? 아니면 전혀 중요합니까? 어쩌면 이것에 대한 모범 사례가 있을까요?연산자를 멤버 함수 또는 비 멤버 (친구) 함수로 오버로드합니까?
답변
각 운영자마다 고유 한 고려 사항이 있습니다. 예를 들어 < < 연산자 (비트 출력이 아닌 스트림 출력에 사용되는 경우)는 첫 번째 매개 변수로 ostream을 가져 오므로 클래스의 멤버가 될 수 없습니다. 만일 당신이 덧셈 연산자를 구현한다면, 당신은 아마 양쪽의 자동 형 변환으로부터 이익을 얻고 싶을 것입니다. 따라서 비회원도 같이 갈 것입니다.
상속에서 공통적 인 패턴은 가상 멤버 함수의 관점에서 비 멤버 연산자를 구현하는 것입니다 (예 : 연산자 < <은 전달되는 객체에 가상 함수 print()를 호출 함).
이 모범 사례처럼 아무것도 없지만 당신이 오버로드 된 연산자에 따라 달라집니다 .. 예컨대 들어
.
>> 및 < <을 멤버 함수로서 오버로드 될 수 없다.
- 은 다음과 같이 수행 할 가정 : 으로 obj1 = 2 * obj2보다 다음 비 멤버 함수에 대한 이동합니다. 비 멤버 함수는이 개 매개 변수를 단 1 파라미터 (호출 객체 impcliitly 전달되는) 반면 멤버 함수의 과부하 이진 연산자 들어
걸립니다.
op를 구현하는 경우 대부분 op =을 구현해야합니다. 즉, + 연산자를 오버로드하는 경우 + =를 구현해야합니다. 후행 증가 또는 과부하 + 연산자를 수행하는 경우 const가 객체에 반환되는지 확인하십시오. 연산자 +를 오버로드하면 멤버가 아닌 연산자로 구현하고 + 연산자를 사용합니다. 예를 들면.
'const A '를 반환하는 점은 무엇입니까? 나는 이것을 (const 값을 반환하는) 몇 번 보았고 어떤 실용적인 이유도 발견하지 못했습니다 ... –
@Matthieu M., "(a + b) = c"를 쓰지 못하도록합니다. 이것은 이미 기본적으로 불가능합니다. int와 같은 기본 유형. –
@ Jagannath, 두 매개 변수 선언에 대해 "const"를 잊어 버렸습니다. –
이진 연산자의 경우 구성원 함수의 한 가지 제한은 왼쪽 개체가 클래스 형식이어야한다는 것입니다. 이것은 연산자를 대칭 적으로 사용하는 것을 제한 할 수 있습니다. 당신이 연산자를 구현 + 멤버 함수로, str("1") + "2"
컴파일 반면, "1" + str("2")
가 컴파일되지 않습니다
class str
{
public:
str(const char *);
str(const str &other);
};
경우
는 간단한 문자열 클래스를 생각해 보자.그러나 operator +를 비 멤버 함수로 구현하면 두 명령문 모두 합법적입니다.
스트리밍 연산자 (< < 및 >>)를 구현하려는 경우 개체가 연산자 왼쪽에 있으므로 멤버가 아닌 메서드가됩니다.
->,() 또는 []를 구현하려는 경우 자연스럽게 구성원 메소드입니다.
기타 (비교 및 수학)에 대해서는 Boost.Operators을 확인해야합니다. 실제로 도움이됩니다. 다음 연산자를 구현하려는 경우 예를 들어
:
class MyClass: boost::operator::addable<MyClass,int> // no need for public there
{
public:
MyClass& operator+=(int);
private:
};
는 2 operator+
자동 드릴 것입니다 비회원으로 생성됩니다
MyClass& MyClass::operator+=(int);
MyClass operator+(const MyClass&, int);
MyClass operator+(int, const MyClass&);
을 만 작성해야 자동 전환의 이점을 누릴 수 있습니다. 그리고 그들은 operator+=
이라는 용어로 효율적으로 구현 될 것이므로 코드를 한 번만 작성하십시오.
"C++ 코딩 표준 : 101 규칙, 가이드 라인 및 모범 사례"를 참조하십시오. 비 멤버 함수로 수행 할 수있는 경우 비 멤버 함수 (같은 네임 스페이스에서)로 수행하십시오.
이유 중 하나는 암시 적 유형 변환에서 더 잘 작동한다는 것입니다. 예 : 오버로드 된 연산자 *가있는 복합 클래스가 있습니다. 2.0 * aComplexNumber를 쓰고 싶다면 operator *가 비 멤버 함수 여야합니다.
커플 링이 적습니다. 비 멤버 함수는 멤버 함수보다 덜 밀접하게 결합됩니다. 이것은 거의 항상 좋은 것입니다.
- 1. (비 멤버) 함수
- 2. 연산자 오버로드 : 멤버 함수 대 비 멤버 함수?
- 3. Objective-C의 비 멤버 함수
- 4. 비 객체의 멤버 함수 check()
- 5. "비 객체의 멤버 함수 호출"
- 6. C++에서 정적 함수로 멤버 함수 변환
- 7. 비 정적 멤버 함수에 대한 C++ 함수 포인터 (클래스 멤버)
- 8. 속보 공공 멤버 함수
- 9. : 비 객체 멤버 함수 setTimezone()를 호출하는
- 10. 비 객체에서 rollback() 멤버 함수 호출
- 11. (단순?) 포인터 멤버 함수 질문 비 정적에
- 12. Magento 멤버 함수 호출 getGrandTotal() 비 객체에서
- 13. 함수 포인터가 멤버 함수
- 14. 멤버 함수 포인터를 호출하려면 어떻게해야합니까?
- 15. 오류 메시지 'class :: function': 비 정적 멤버 함수 호출이 잘못되었습니다.
- 16. 가상 멤버 함수 필요성
- 17. 클래스의 멤버 함수를 콜백 함수로 전달하십시오.
- 18. 클래스 멤버 함수를 c- 함수로 바인딩
- 19. 멤버 함수 대 비회원 함수?
- 20. 정적 멤버 함수
- 21. Boost.Variant에 멤버 함수 추가하기
- 22. 클래스와 멤버 함수 매핑하기
- 23. C++ 멤버 함수 바인딩
- 24. 오버로드> 멤버 함수
- 25. C++ 멤버 함수 포인터
- 26. const 멤버 함수 호출
- 27. const 멤버 함수 설명은
- 28. C++ const 멤버 함수
- 29. 다형 멤버 함수 포인터
- 30. 멤버 함수 호출 getAllHash
cout 및 cin은 iostream의 클래스 인스턴스이며 오버로드 할 수 없으며 OP는 연산자 오버로드에 대해 이야기합니다. –
감사합니다. – Ashish
'<<' and '>>는 멤버 함수로 오버로드 될 수 있습니다. 스트림 추출/삽입 연산자로 사용하려는 경우가 아닙니다. 데니스 리치 (Dennis Ritchie)가 의도 한 것처럼 시프트 연산자로 사용하려면 아무런 문제가 없습니다. –