virtual 키워드를 직접 사용하는 언어
1. C++
- 가장 대표적인 virtual 키워드 사용 언어
- 가상 함수, 가상 소멸자, 다형성 구현
2. C#
- 메서드를 오버라이드할 수 있게 할 때 virtual을 사용
- 자식 클래스에서는 override로 재정의
3. D 언어 (D Programming Language)
- 기본이 virtual이지만 명시적으로 사용 가능
4. Hack (HHVM/Hacklang)
- PHP와 유사하지만 OOP 확장으로 virtual 키워드 사용
5. Dart (일부 버전에서 사용 가능했던 예전 문법)
- 현재는 virtual 키워드를 거의 사용하지 않지만, 초기 문법에서 존재했음
🔍 “virtual” 개념은 있지만 키워드가 없는 언어
다음 언어들은 가상 메서드/다형성을 지원하지만 virtual 키워드는 없음:
- Java (기본 메서드가 모두 virtual, 단 final로 막음)
- Python (모든 메서드가 virtual; ABC로 가상 인터페이스 구현)
- Swift (기본 virtual, override만 명시)
- Kotlin (default final → open으로 virtual과 유사 기능)
- Ruby (모든 메서드 virtual)
📌 정리
| C++ | ✔ 사용 |
| C# | ✔ 사용 |
| D | ✔ 사용 |
| Hack | ✔ 사용 |
| Dart (구버전) | ✔ 일부 사용 |
| Java/Python/Kotlin 등 | ✖ 개념은 있지만 키워드는 없음 |
============================================================================================




============================================================================================
1. 프로그래밍 언어에서 static 키워드의 용도 (이모티콘 제거 버전)
프로그래밍 언어에서 static 키워드는 언어마다 의미가 다르지만, 공통적으로 “정적인(고정된) 저장·동작 방식”을 나타낸다. 대표적인 용도는 다음과 같다.
1) 정적 변수 (static variable)
변수가 프로그램 실행 동안 단 한 번만 생성되고, 범위를 벗어나도 값이 유지된다.
C/C++ 예
2) 정적 함수 / 내부 연결 (static function)
C/C++에서 static을 함수나 전역 변수에 붙이면 해당 파일 내부에서만 접근 가능하다.
3) 클래스 정적 멤버 (static fields / methods)
Java, C#, C++, Python 등에서 클래스의 인스턴스가 아닌 클래스 자체에 속한 멤버를 만든다.
Java 예
4) 정적 바인딩 / 정적 메서드
Java, C#, C++ 등에서 오버라이드되지 않는 메서드를 만들 때 사용한다.
정리
static의 핵심 개념은 두 가지이다.
- 메모리 수명 고정 (프로그램 종료까지 유지)
- 속성 고정 (클래스 소속, 파일 내부 제한 등)
2. 프로그래밍 언어별 static 사용 예 (이모티콘 제거 버전)
아래는 대표적인 언어별로 static이 어떻게 사용되는지 정리한 것이다.
C — 정적 변수 및 내부 연결
정적 지역 변수
파일 내부에서만 보이도록 제한
프로그래밍 언어별 static 사용 예 (이모티콘 제거 버전)
아래는 대표적인 언어별로 static이 어떻게 사용되는지 정리한 것이다.
C — 정적 변수 및 내부 연결
정적 지역 변수
파일 내부에서만 보이도록 제한
C++ — 정적 변수, 정적 멤버, 내부 연결
클래스 정적 멤버
정적 지역 변수
Java — 클래스 변수 / 클래스 메서드
C# — 정적 필드, 정적 메서드, 정적 클래스
Python — @staticmethod
JavaScript — static 메서드
PHP — 클래스 정적 멤버
1. x는 "일반 변수"라 매번 새로 만들어짐
x는 int x = 10; 이라고 되어 있는 지역 변수입니다.
- sub()를 호출할 때마다 새로 10을 넣어서 만들어짐
- 함수가 끝나면 없어짐
그래서 출력할 때마다 x는 항상 10입니다.
2. y는 "static 변수"라 딱 한 번만 만들어짐
static int y = 10; 은 정적 변수인데,
- 프로그램 실행 중 단 한 번만 만들어지고 초기화됨
- 함수가 끝나도 없어지지 않고 그대로 남아 있음
- 다음에 sub()가 다시 호출되면 이전에 증가한 값 그대로 사용
그래서 y는 호출할 때마다 계속 증가합니다.
3. 실제 실행 흐름
첫 번째 sub() 호출
- x = 10
- y = 10 (처음 딱 1번 만들어짐)
→ 출력: 10 10
→ x++ → 사라짐
→ y++ → 11 저장됨
두 번째 sub() 호출
- x = 10 (새로 만들어짐)
- y = 11 (전에 저장된 값 그대로)
→ 출력: 10 11
→ y++ → 12
세 번째 sub() 호출
- x = 10
- y = 12
→ 출력: 10 12
4. 최종 출력 결과가 이렇게 나오는 이유
- x는 매번 10에서 새로 시작
- y는 이전 값이 살아있어 증가된 값이 사용
정리하면:
x는 매번 처음부터 시작하는 아이
y는 기억력이 좋아서 지난번 값도 기억하는 아이
============================================================================================

1. C 언어의 auto — “지역 변수”라는 뜻일 뿐 (사실상 의미 없음)
C에서 auto는 다음과 같다:
이렇게 써도
과 완전히 동일하다.
이유
- C에서는 함수 안에 선언한 변수는 기본이 auto(자동 저장소)
- 즉, 함수가 끝나면 사라지는 지역 변수라는 의미
- programmers가 auto를 명시할 필요도 없고 거의 사용하지 않음
C에서 auto는 사실상 “쓸 일 없는 키워드”
2. C++의 auto — “타입 자동 추론(type inference)”
C++11 이후 auto는 완전히 다른 의미를 가진다.
C++에서 auto는 컴파일러가 타입을 자동으로 정해주는 기능
예:
또한 복잡한 타입을 단순하게 만들 때 유용하다:
→ 이렇게 안 써도 됨
핵심
- 타입을 추론해주는 아주 중요한 기능
- C++에서 많이 쓰이는 현대적 문법
3. 요약 비교표
| auto 의미 | 지역 변수(자동 저장소) | 변수 타입 자동 추론 |
| 사용 여부 | 거의 쓰지 않음 | 매우 많이 사용 |
| 기능 | 사실상 의미 없음 | 현대 C++의 핵심 기능 |
| 예 | auto int x; = int x; | auto x = 10; → int 자동 결정 |
한 줄 요약
C의 auto = 의미 없는 지역 변수 선언
C++의 auto = 타입을 컴파일러가 알아서 정해주는 기능
============================================================================================
네, 반드시 정의 부분을 써야 합니다.
안 쓰면 링크 오류(linker error)가 발생합니다.
왜 정의를 반드시 써야 하는가?
여기서는 count라는 정적 멤버가 있다는 "선언"만 한 것입니다.
하지만 정적 멤버 변수는 객체 안에 포함되지 않고,
프로그램 전체에서 단 하나의 실제 저장 공간(메모리)에 존재해야 합니다.
그러므로 다음처럼 클래스 밖에서 "정의(definition)"를 반드시 해줘야 합니다.
이걸 작성해줘야 비로소 count가 메모리에 만들어집니다.
정의를 안 쓰면 어떤 일이 일어나는가?
컴파일은 되지만 링크 단계에서 오류가 납니다.
보통 이런 에러가 뜹니다:
이는 "count가 있다는 건 알겠는데, 실제로 만들어진 적이 없다"는 의미입니다.
왜 static 멤버만 이런 문제가 생기는가?
- 일반 멤버 변수 → 객체가 만들어질 때마다 생성됨
- static 멤버 변수 → 객체와 상관없이 클래스당 1개만 존재
즉, 일반 멤버는 각 객체가 메모리를 갖지만
static 멤버는 클래스 밖에서 따로 정의해야 메모리가 생김.
결론
- static 멤버 변수는 선언만으로는 부족함
- 클래스 밖에서 반드시 정의가 필요
- 그렇지 않으면 링크 오류 발생
============================================================================================







1. 업캐스팅(Upcasting)
자식 클래스 → 부모 클래스 로 캐스팅하는 것
즉, “아래에서 위로” 올라가는 캐스팅.
특징
- 자동으로 가능(Implicit cast)
- 안전함
- 자식에 있던 기능은 숨겨지고 부모에 있는 기능만 사용 가능
예 (C++ / Java 공통 개념)
왜 안전한가?
Dog는 Animal의 일종이기 때문에
“개를 동물로 다루는 것”은 문제가 되지 않음.
2. 다운캐스팅(Downcasting)
부모 클래스 → 자식 클래스 로 캐스팅
즉, “위에서 아래로” 내려가는 캐스팅.
특징
- 수동으로 명시해야 함(Explicit cast)
- 위험할 수 있음
- 실제로 그 객체가 자식 타입일 때만 안전함
예
그러나:
이 경우 런타임 오류 또는 정의되지 않은 동작이 발생한다.
C++에서는 이렇게 하는 것이 안전:
또는 Java에서는:
3. 업캐스팅과 다운캐스팅 비교
| 방향 | 자식 → 부모 | 부모 → 자식 |
| 가능 여부 | 자동 가능 | 명시적 필요 |
| 안전성 | 안전함 | 위험할 수 있음 |
| 사용 가능한 멤버 | 부모 클래스 멤버만 | 자식 클래스 멤버 사용 가능 |
| 사용 목적 | 다형성(polymorphism) 활용 | 자식의 기능을 다시 사용하고 싶을 때 |
4. 쉬운 비유
- 업캐스팅:
“고양이를 ‘동물’이라고 부르는 것”
→ 항상 안전함 - 다운캐스팅:
“동물을 ‘고양이’로 부르는 것”
→ 그 동물이 실제 고양이일 때만 안전함
============================================================================================

1. 오버로딩(Overloading)
같은 이름의 함수를 여러 개 만들되, 매개변수만 다르게 하는 것.
즉,
- 함수 이름: 같음
- 매개변수 타입/개수: 다름
- 반환형은 상관없음(하지만 반환형만 다르고 매개변수가 같으면 안 됨)
예: 함수 오버로딩
결과
특징 요약
- 같은 이름, 다른 매개변수
- 컴파일 시간에 결정 (compile-time)
- 한 클래스 안에서 사용
- 상속과 관계 없음
2. 오버라이딩(Overriding)
부모 클래스의 함수를 자식 클래스에서 다시 정의하는 것.
즉,
- 함수 이름: 같음
- 매개변수: 같음
- 반환형: 같거나 호환되는 형태
- 반드시 상속 관계가 있어야 함
- virtual 키워드로 다형성(polymorphism) 사용
예: 오버라이딩
결과
왜 Dog의 speak()가 호출될까?
- 부모 포인터(Animal*)로 자식(Dog)을 가리켜도
- virtual 함수는 런타임에 실제 객체 타입(Dog)을 보고 실행된다.
특징 요약
- 이름 같음
- 매개변수 같음
- 반환형 같음
- 반드시 상속 관계
- 목적: 다형성 구현
- 실행 시간에 결정(run-time)
3. 오버로딩 vs 오버라이딩 비교표
| 의미 | 동일 이름, 다른 매개변수 | 부모 기능을 자식이 재정의 |
| 관계 | 같은 클래스 | 상속 관계 필요 |
| 매개변수 | 달라야 함 | 같아야 함 |
| 반환형 | 상관 없음 | 같거나 호환 |
| virtual 필요? | 필요 없음 | 필요함 |
| 결정 시점 | 컴파일 시간 | 런타임 |
| 목적 | 편의성, 다형적 호출 X | 다형성(polymorphism) |
4. 아주 쉬운 비유
오버로딩
“print라는 이름의 기계를 여러 버전으로 만드는 것”
- print(int)
- print(double)
- print(string)
사용자가 넣는 값에 맞게 컴파일러가 자동으로 골라줌.
오버라이딩
“부모가 만들어놓은 기능을 자식이 고쳐 쓰는 것”
- Animal의 speak()
- Dog가 speak()를 자기 방식으로 다시 만듬
============================================================================================
