객체 슬라이싱은 c++ 상속만의 문제로 상속관계에서 의도치않은 결과를 일으킬 수 있다.


처음에는 animalRef 레퍼런스을 통해 speak()함수를 호출하였다.
이는 animalRef를 통해 kitty객체를 가리켰다고 할 수 있다.
두번 째에는 animalObj 객체를 생성하여 kitty객체를 연결하였다.
이 때는

animal obj에 Cat 데이터가 없으므로 copy constructor가 실행된다.
double 타입의 animal 데이터는 바로 copy되지만
VT는 특수한 변수이므로 copy가 일어나지않고 Animal 가상테이블을 따라간 뒤 speak()함수를 실행한다.
즉, 객체 슬라이싱이란 derived 클래스에서 base 클래스로 복사될 때 derived 클래스의 정보는 잘려나간다는 것이다.

어떤 함수를 만들었을 때 인수를 객체 value로 받게되면 객체 슬라이싱이 일어나면서 의도하지 않은 현상이 일어날 수 있다.
그래서 더 방어적인 프로그래밍을 위한 방법으로
copy constructor를 삭제할 수 있다.

copy constructor와 copy assignment를 없애주게 되면 컴파일시 copy constructor를 불러오지 못해
원천적인 원인을 제거할 수 있다.
하지만 이렇게하면 derived 클래스끼리의 copy constructor도 막는다는 점이다.

라고 실행했을 때 base클래스의 지워진 copy constructor때문에 컴파일이 되지않는다.
이를 해결하는 방법으로는
copy constructor를 protected:로 보내주는 것이다.

derived 클래스가 copy constructor를 호출할 때
base 클래스내의 copy constructor 또한 호출되야 하는데 이 때 protected안에 있기 때문에
derived클래스에서 base클래스의 copy constructor를 호출할 수 있다.
아니면

함수를 제공하는 방법도 있다.
그렇지만 가장 좋은 방법은 base클래스를 순수 가상 클래스로 두는 것이다.
상속 구조는 다른 문제를 일으킬 수 있는데
operating overloading에서 일어날 수 있다.
Animal 클래스에 "=="연산자를 정의한다고하자
(여기서 animalData이 private:가 아닌 public:에 있다고하자)
public:
double animalData = 0.0f;
};

그리고 Cat 클래스를
class Cat : public Animal
{
public:
Cat(double d): catData{d} {};
void speak() override
{
std::cout << "meow~" << std::endl;
}
public:
double catData;
};
라 하고
main함수에서

로 실행하면 
Cat 클래스의 double catData에 서로 다른 데이터가 들어가 if의 조건이 false가 될 것이라는 기대와는 다르게 same이 나온다. 이는 base클래스인 Animal의 double animalData = 0.0f;로 서로 비교되었기 때문이다.
이를 해결하기 위해서는 Cat 클래스에도

"=="연산자에 대한 정의를 해주어야한다.