Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 연산자 오버로딩(Operator Overloading) 완벽 가이드: 개념부터 실전 예제까지

C#에서 연산자 오버로딩(Operator Overloading)이란 사용자 정의 타입(클래스나 구조체)에 대해 +, -, == 같은 기존 연산자가 동작하도록 재정의하는 기능입니다. 오버로드된 연산자는 특수한 이름을 가진 함수로, operator 키워드 뒤에 정의하려는 연산자 기호를 붙여 선언합니다. 일반 함수와 마찬가지로 반환 타입과 매개변수 목록을 가질 수 있습니다.

오버로드 가능한 연산자와 불가능한 연산자

모든 연산자를 오버로딩할 수 있는 것은 아닙니다. 아래 표는 C#에서 오버로드 가능 여부를 정리한 것입니다.

번호연산자 및 설명
1+, -, !, ~, ++, --
단항(unary) 연산자로, 하나의 피연산자를 받으며 오버로딩이 가능합니다.
2+, -, *, /, %
이항(binary) 산술 연산자로, 두 개의 피연산자를 받으며 오버로딩이 가능합니다.
3==, !=, <, >, <=, >=
비교 연산자도 오버로딩할 수 있습니다. 단, ==와 !=는 반드시 쌍으로 함께 정의해야 합니다.
4&&, ||
조건 논리 연산자는 직접 오버로딩할 수 없습니다. 다만 &와 |를 오버로드하면 간접적으로 사용 가능합니다.
5+=, -=, *=, /=, %=
복합 대입 연산자는 직접 오버로딩할 수 없습니다. 대신 해당 산술 연산자(+, - 등)를 오버로드하면 자동으로 동작합니다.
6=, ., ?:, ->, new, is, sizeof, typeof
이 연산자들은 오버로딩이 불가능합니다.

연산자 오버로딩 문법

오버로드된 연산자는 반드시 public static으로 선언해야 하며, 다음과 같은 형태로 정의합니다.

public static Box operator+ (Box b, Box c) { }

예제 코드

다음은 C#에서 연산자 오버로딩을 활용해 두 개의 Box 객체를 더하는 전체 예제입니다.

using System;

namespace OperatorOvlApplication {
    class Box {
        private double length;   // 상자의 길이
        private double breadth;  // 상자의 너비
        private double height;   // 상자의 높이

        public double getVolume() {
            return length * breadth * height;
        }

        public void setLength(double len) {
            length = len;
        }

        public void setBreadth(double bre) {
            breadth = bre;
        }

        public void setHeight(double hei) {
            height = hei;
        }

        // + 연산자를 오버로드하여 두 Box 객체를 더한다.
        public static Box operator+ (Box b, Box c) {
            Box box = new Box();
            box.length = b.length + c.length;
            box.breadth = b.breadth + c.breadth;
            box.height = b.height + c.height;
            return box;
        }
    }

    class Tester {
        static void Main(string[] args) {
            Box Box1 = new Box();  // Box 타입의 Box1 선언
            Box Box2 = new Box();  // Box 타입의 Box2 선언
            Box Box3 = new Box();  // Box 타입의 Box3 선언
            double volume = 0.0;   // 부피를 저장할 변수

            // Box1 크기 설정
            Box1.setLength(6.0);
            Box1.setBreadth(7.0);
            Box1.setHeight(5.0);

            // Box2 크기 설정
            Box2.setLength(12.0);
            Box2.setBreadth(13.0);
            Box2.setHeight(10.0);

            // Box1의 부피 출력
            volume = Box1.getVolume();
            Console.WriteLine("Volume of Box1 : {0}", volume);

            // Box2의 부피 출력
            volume = Box2.getVolume();
            Console.WriteLine("Volume of Box2 : {0}", volume);

            // 오버로드된 + 연산자로 두 객체를 더함
            Box3 = Box1 + Box2;

            // Box3의 부피 출력
            volume = Box3.getVolume();
            Console.WriteLine("Volume of Box3 : {0}", volume);
            Console.ReadKey();
        }
    }
}

실행 결과

Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400

정리

위 예제에서 볼 수 있듯이, operator+를 정의하면 Box1 + Box2처럼 객체끼리 자연스럽게 덧셈을 수행할 수 있습니다. 이처럼 연산자 오버로딩을 활용하면 벡터, 행렬, 좌표 등 수학적 개념을 다루는 코드를 훨씬 직관적이고 가독성 있게 작성할 수 있습니다. 다만 남용하면 코드의 의미를 혼란스럽게 만들 수 있으므로, 연산자의 원래 의미와 일치하는 경우에만 사용하는 것이 좋습니다.