부모 클래스를 인터페이스로 쓰려고 가상함수 쓰는거 맞지 않음? 뼈대만 부모클래스로 만들어두고 자식클래스 원하는대로 찍어내서 쓰는거
글쓴 ㅇㅇ(218.237)2025-03-14 23:38:00
답글
명시된 변수 타입에 관계없이 실제 인스턴스의 메소드를 호출하려면 가상함수여야만 하니까
ㅇㅇ 1(211.197)2025-03-14 23:44:00
답글
그니까 배울때 부모클래스 포인터에다가 자식객체 넣고 부모가 아닌 자식객체 메서드 호출하려고 쓰는것 ==> 부모클래스를 인터페이스로 써먹을수 있다라고 배웠는데 이게 뜻이 다른건가? 제대로 이해한거 맞지?
글쓴 ㅇㅇ(218.237)2025-03-14 23:49:00
답글
가상함수 안쓰면 부모에서 구현된거만 쓰게됨
ㅇㅇ 2(221.147)2025-03-15 00:00:00
다형성을 이해하시오
ㅇㅇ 2(221.147)2025-03-14 23:37:00
답글
이해하고있다고 생각했는데 완벽하게 설명해보라 했을때 좀 우물쭈물하면 제대로 이해못한거겠지
글쓴 ㅇㅇ(218.237)2025-03-14 23:41:00
C# 자식 클래스에서 new 랑 override 차이 보면 될듯?
익명(fujiwara1)2025-03-15 00:00:00
c++은 virtual 선언 안하면 무조건 멤버함수임 - dc App
ㅇㅇ 3(59.23)2025-03-15 00:38:00
단순히 이름 같은건 오버로딩
ㅇㅇ 4(211.48)2025-03-15 18:17:00
함수 오버로딩 : 함수 이름이 똑같으면 컴파일러가 어떤 함수를 호출할지 모르는데 인자가 다르다면 컴파일러는 함수를 호출할때 들어가는 인자 들을 보고 호출해야하는 함수를 구분 할 수가 있음.
함수 오버라이딩 : 부모 클래스 포인터에 자식 클래스를 할당 시킬 때 만약 부모 클래스에 Speak() 함수가 있고 자식 클래스에 Speak() 함수가 있을 때 부모 포인터지만 할당 시킨 객체는 자식 이므로 자식 클래스의 Speak() 함수가 호출될거라고 생각하지만 실제로는 부모 클래스의 함수가 호출 됨.
그 이유는 정적 바인딩 때문인데 컴파일러는 class에 함수가 있으면 해당 멤버 함수를 어딘가에 만들어 놓고 객체가 자신의 멤버 함수를 호출 할때 자신의 객체를 인자로 보냄.
ㅇㅇ 5(58.233)2025-03-19 14:56:00
답글
즉, 클래스 객체마다 함수를 가지고 있는 것이 아니라 메모리에 한번만 저장되고 함수를 호출할떄마다 해당 메모리에 저장된 함수를 호출하는 것임. 그 어딘가는 코드 영역 or 텍스트 영역일 것임.
다시 돌아와서 자식 객체를 할당한 부모 포인터의 Speak 함수를 호출 할때, Speak 함수에 전달되는 객체는 부모 클래스 이기 떄문에 부모의 Speak 함수가 호출 되는것. 하지만 우리가 원하는 것은 부모 멤버 함수가 아니라 자식 멤버 함수임. 이걸 하기 위해서는 동적 바인딩을 알아야됨.
ㅇㅇ 5(58.233)2025-03-19 15:00:00
답글
부모 클래스에 멤버 함수를 virtual 키워드를 사용해서 가상 함수로 만들게 되면 가상 테이블이라는게 만들어짐. 부모 클래스의 Speak() 함수가 가상 함수가 되면 해당 함수의 주소는 부모 클래스의 가상 테이블에 저장됨.
또한 해당 부모 클래스의 자식 클래스도 똑같은 Speak() 함수가 있으면 부모 클래스의 Speak() 함수가 virtual 이기 때문에 해당 자식 멤버 함수도 가상 테이블에 저장 됨.
이렇게 가상 테이블이 어딘가에 생성이됨. 이제 이걸 어떻게 사용하냐인데 우리가 객체를 만들게 됐을때 해당 객체가 동적 바인딩이 된 객체라면 생성될때 해당 가상 테이블을 가르키는 포인터를 하나 달고나옴.
그럼 이제 우리가 부모 클래스 포인터에 자식 클래스를 할당했을 때 Speak 함수를 호출하면
ㅇㅇ 5(58.233)2025-03-19 15:19:00
답글
정적 바인딩에서는 부모 클래스의 함수를 호출 했지만 동적 바인딩에서는 객체가 가르키고있는 가상 테이블의 함수를 호출하게 되니까 부모 객체 포인터라도 할당된 자식 객체의 함수가 호출되는 거임. 왜냐? 생성된 자식 객체는 가상 테이블을 가지고있으니까 그 테이블의 함수를 호출하면 되는거니까
즉, 한 부모 에게서 상속 받은 함수가 있는데 이걸 다른 각각의 자식들이 자신에 맞게 같은 함수라도 동작이 다르게 다양하게 사용하는 것을 다형성 이라고 하는 것.
무조건 가상함수 써야 되는게 맞음 ㅇㅇ
문법은 완벽하게 깨달았다 생각하다가도 잘못알던거나 헷갈리는게 자꾸 생기네
이거 제대로 할려면 단순히 문법을 외우는게 아니라 왜 가상함수를 쓰는지를 이해해야...
부모 클래스를 인터페이스로 쓰려고 가상함수 쓰는거 맞지 않음? 뼈대만 부모클래스로 만들어두고 자식클래스 원하는대로 찍어내서 쓰는거
명시된 변수 타입에 관계없이 실제 인스턴스의 메소드를 호출하려면 가상함수여야만 하니까
그니까 배울때 부모클래스 포인터에다가 자식객체 넣고 부모가 아닌 자식객체 메서드 호출하려고 쓰는것 ==> 부모클래스를 인터페이스로 써먹을수 있다라고 배웠는데 이게 뜻이 다른건가? 제대로 이해한거 맞지?
가상함수 안쓰면 부모에서 구현된거만 쓰게됨
다형성을 이해하시오
이해하고있다고 생각했는데 완벽하게 설명해보라 했을때 좀 우물쭈물하면 제대로 이해못한거겠지
C# 자식 클래스에서 new 랑 override 차이 보면 될듯?
c++은 virtual 선언 안하면 무조건 멤버함수임 - dc App
단순히 이름 같은건 오버로딩
함수 오버로딩 : 함수 이름이 똑같으면 컴파일러가 어떤 함수를 호출할지 모르는데 인자가 다르다면 컴파일러는 함수를 호출할때 들어가는 인자 들을 보고 호출해야하는 함수를 구분 할 수가 있음. 함수 오버라이딩 : 부모 클래스 포인터에 자식 클래스를 할당 시킬 때 만약 부모 클래스에 Speak() 함수가 있고 자식 클래스에 Speak() 함수가 있을 때 부모 포인터지만 할당 시킨 객체는 자식 이므로 자식 클래스의 Speak() 함수가 호출될거라고 생각하지만 실제로는 부모 클래스의 함수가 호출 됨. 그 이유는 정적 바인딩 때문인데 컴파일러는 class에 함수가 있으면 해당 멤버 함수를 어딘가에 만들어 놓고 객체가 자신의 멤버 함수를 호출 할때 자신의 객체를 인자로 보냄.
즉, 클래스 객체마다 함수를 가지고 있는 것이 아니라 메모리에 한번만 저장되고 함수를 호출할떄마다 해당 메모리에 저장된 함수를 호출하는 것임. 그 어딘가는 코드 영역 or 텍스트 영역일 것임. 다시 돌아와서 자식 객체를 할당한 부모 포인터의 Speak 함수를 호출 할때, Speak 함수에 전달되는 객체는 부모 클래스 이기 떄문에 부모의 Speak 함수가 호출 되는것. 하지만 우리가 원하는 것은 부모 멤버 함수가 아니라 자식 멤버 함수임. 이걸 하기 위해서는 동적 바인딩을 알아야됨.
부모 클래스에 멤버 함수를 virtual 키워드를 사용해서 가상 함수로 만들게 되면 가상 테이블이라는게 만들어짐. 부모 클래스의 Speak() 함수가 가상 함수가 되면 해당 함수의 주소는 부모 클래스의 가상 테이블에 저장됨. 또한 해당 부모 클래스의 자식 클래스도 똑같은 Speak() 함수가 있으면 부모 클래스의 Speak() 함수가 virtual 이기 때문에 해당 자식 멤버 함수도 가상 테이블에 저장 됨. 이렇게 가상 테이블이 어딘가에 생성이됨. 이제 이걸 어떻게 사용하냐인데 우리가 객체를 만들게 됐을때 해당 객체가 동적 바인딩이 된 객체라면 생성될때 해당 가상 테이블을 가르키는 포인터를 하나 달고나옴. 그럼 이제 우리가 부모 클래스 포인터에 자식 클래스를 할당했을 때 Speak 함수를 호출하면
정적 바인딩에서는 부모 클래스의 함수를 호출 했지만 동적 바인딩에서는 객체가 가르키고있는 가상 테이블의 함수를 호출하게 되니까 부모 객체 포인터라도 할당된 자식 객체의 함수가 호출되는 거임. 왜냐? 생성된 자식 객체는 가상 테이블을 가지고있으니까 그 테이블의 함수를 호출하면 되는거니까 즉, 한 부모 에게서 상속 받은 함수가 있는데 이걸 다른 각각의 자식들이 자신에 맞게 같은 함수라도 동작이 다르게 다양하게 사용하는 것을 다형성 이라고 하는 것.