본문 바로가기

C

c++ class에서 object slicing 문제 발생

코드 >>

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
 
class Animal
{
public:
    Animal() = default;
    Animal& operator=(Animal other) = delete;
    virtual void speak()
    {
        std::cout << "Animal" << std::endl;
        
    }
    virtual ~Animal() = default;
    double publicAnimalData = 0.0f;
protected:
    // 방어적 프로그래밍
    // copy constructor가 발생하지 않게 만든다.
    // Derived class에서 copy constructor를 가능하게 함
    Animal(const Animal& a) = default;
    
private:
    double animalData = 0.0f;
};
 
class Cat : public Animal
{
public:
    Cat(double d) : catData{ d } {};
    void speak() override
    {
        std::cout << "meow~" << std::endl;
    }
    double publicCatData;
private:
    double catData;
};
 
void f(Animal& animal) {
    animal.speak(); // 무조건 Reference로 받아야 object slicing 발생 X
}
 
bool operator==(const Animal& lhs, const Animal& rhs)
 
{
    std::cout << "animal comp" << std::endl;
    return lhs.publicAnimalData == rhs.publicAnimalData;
}
bool operator==(const Cat& lhs, const Cat& rhs)
 
{
    std::cout << "cat comp" << std::endl;
    return lhs.publicCatData == rhs.publicCatData;
}
 
int main()
{
    Cat kitty{ 1.0 };
    Cat nabi{ kitty };
    
    //kitty.speak(); 
 
    Animal& animalRef = kitty;
    animalRef.speak(); // meow  kitty object ->  (Reference로 받아서 kitty의 *VT(Cat의 speak 함수 가르킴), animalData, catData)
 
    std::cout << "---------------" << std::endl;
    //Animal animalObj = kitty; // copy constructor 생성됨(내부 데이터의 copy),그러나 kitty의 *virtual table은 copy가 발생하지 않음
                              // 따라서 animalObj의 VT는 Animal VT를 가르킴
    //animalObj.speak(); // animal -> object slicing 발생
 
    Cat kitty1{ 1.0 };
    Cat nabi1{ 1.0 };
    std::cout << (kitty1 == nabi1) << std::endl// same (이상함) base operator의 equality operator가 출력됨
                                                 // 별도로 cat 간의 equality operator도 출력해주어야 함
    return 0;
 
}