Programming and my thoughts

4. C++ 에서 객체 잘림(Object Slicing)이란 무엇인가?


1-10.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
 
class Engineer {
    public:
        void Assemble();
        
        int salary;
};
 
class Engineer_LVL2 : public Engineer {
    public:
        void Disassemble();
        
        int incentive;
};
 
int main() {
    Engineer *= new Engineer();
    e->salary = 300;
    Engineer_LVL2 *e2 = new Engineer_LVL2();
    e2->salary = 350;
    e2->incentive = 20;
    
    e = e2;
    
    std::cout << e->salary;
    // ▼ Compile error
    // std::cout << e->incentive;
    
    return 1;
}
cs


* 소스 하이라이트 스크립트를 Color Scripter 로 변경했다.

기존 것은 소스 복사를 하니 다 한 줄로 붙여넣기가 되어서 소스 복사 하는데에 애로사항이 있었다.


1
350
cs


객체 잘림은 베이스 클래스에 파생 클래스를 대입하면... 멤버중 일부가 잘려나가는 것을 말한다.

위 코드의 경우 Engineer e 에게 Engineer_LVL2 e2 를 대입하니...

e 의 salary 는 350 이 되었는데...

e 의 incentive 는 접근 자체가 불가능하고... (컴파일 에러)

가장 중요한... 여기서 객체 잘림이란... 대입시(=) 우변 e2 의 멤버에 해당하는 incentive 가 사라진 것을 말한다.


5. C++ 에서 가상 함수(Virtual Function)이란 무엇인가?


귀차니즘의 압박으로 코드는 생략...


Java 의 경우 기본적으로 클래스의 모든 멤버 함수들은 동적 바인딩을 한다.

C++ 의 경우 virtual 이라는 키워드가 붙은 멤버 함수들은 동적 바인딩을 하고, 일반 멤버 함수들은 정적 바인딩을 한다.


6. 추상 클래스와 인터페이스랑 무엇이며 둘의 차이점은?


C++ 에는 추상 클래스만 있고...

Java, C# 에는 추상 클래스, 인터페이스가 모두 있다.


C# 으로 참 많은 것들을 만들었는데도... C# 에서는 추상 클래스를 써본 적이 없는 것 같다. (...)


1-11.cpp

1
2
3
4
5
6
7
8
9
class AbstractClass {
    public:
        // 순수 가상 함수
        virtual void AbstractFunction() = 0;
        // 가상 함수
        virtual void NonAbastractFunction();
        // 함수
        void Function();
};
cs


C++ 에서 가상 함수에 = 0 을 붙이면 순수 가상 함수가 되고... 순수 가상 함수를 가진 클래스는 추상 클래스가 된다.


1-12.java

1
2
3
4
interface Interface {
    void FunctionA(int a);
    void FunctionB(int a, int b);
}
cs


Java, C# 에는 interface 라는 키워드가 있는데 이걸 붙이면 인터페이스가 된다.

마찬가지로... abstract 라는 키워드를 붙이면 추상 클래스가 된다.


Java, C# 의 인터페이스는 서로 약간의 차이가 있는데... 이건 여기서는 넘어가도록 한다.


중요한 것은...


1. 추상 클래스와 인터페이스 모두 인스턴스화(객체화)가 불가능하다.

2. 추상 클래스는 순수 가상 함수 뿐만 아니라 구현부를 가진 함수도 가질 수도 있으나... 어쨌든 인스턴스화는 불가능하다.

3. "추상" 이라는 테마를 놓고 봤을 때에는 인터페이스는 이 테마를 가장 잘 표현한 개념이다. (인터페이스가 가진 함수(메서드)들은 모두 순수 가상 함수이기 때문)


이 주제를 가지고 고등학교 객관식 문제를 내면... 아주 어려운 문제를 낼 수도 있을 것이다.

그러나 이런 문제들에 대한 해답은 구글링하면 다 나오는 지식들이기 때문에 외울 필요는 없다고 생각한다.


그럼 둘의 차이점은... (C++ 에는 인터페이스가 없기 때문에 Java 기준으로 설명함)


1. 인터페이스는 구현부를 가질 수 없다. (위의 2 에서 말한 바와 같이 추상 클래스는 가능)

2. 인터페이스는 implements 키워드로 "구현" 되어야 한다.

3. 추상 클래스는 extends 키워드로 "확장" 되어야 한다.

4. 하나의 클래스가 여러개의 인터페이스를 "구현" 할 수 있지만... 추상 클래스는 하나만 "확장" 할 수 있다.


위에서 2, 3 의 경우 인터페이스와 추상 클래스를 인스턴스화 하기 위한 조건을 말한다고 보면 된다.

아무튼 얘네들은 그 자체로는 인스턴스화가 불가능하다. (클래스가 품어줘야 함)