자식 클래스를 할당할때 부모 클래스로 선언하는 이유는 무엇인가요?

익명 사용자의 이미지

class A
{
public:
A();
~A();
};

class B : public A
{
public:
B();
~B();
};

이런 종속관계에 있는 클래스가 있을때

int main()
{
B *Test = new B;
delete B;
}

이런 식으로 자식 클래스를 선언하고 자식 클래스를 할당하면 소멸자에 virtual 명령어를 안넣어도
delete 하면 부모도 죽고 자식도 잘 죽던데 이 코드를

int main()
{
A *Test = new B;
delete B;
}

이렇게 부모 클래스를 선언하고 자식 클래스를 할당해주는 코드를 보여주면서
이게 virtual 명령어를 사용하는 이유다 라고 적혀 있길래
납득이 잘 가지 않아서 질문 드립니다.

이미 B는 A의 종속관계에 있으니 어차피 부모 클래스의 함수는 다 가져다 쓸 수 있을텐데
후자 같은 경우는 어떤 때 사용하는 건지 알 수 있을까요?

억 실수 의 이미지

delete B; 가 아니라 delete Test; 입니다

익명 사용자의 이미지

답변하기 전에.
"선언"은 C++에서 뚜렷한 의미가 있는 정의된 단어이며, 귀하께서는 일반적으로 쓰이지 않는 용법으로 쓰고 계시다는 걸 알려 드려야겠군요.

사람은 눈치가 있기에 대충 써도 대충 알아듣지만, 내용이 복잡해질수록 알아듣기 어렵고 오해가 생기게 됩니다.

답변.

class Base{}; class Derived: public Base {};

C++에서 public 상속의 의미론은 "Derived는 Base이다" 입니다. Derived는 Base가 할 수 있는 것을 모두 할 수 있고, 따라서 Base를 받는 코드는 Derived를 받고도 동작해야 합니다.

그 사실을 가장 뚜렷하게 보여주는 사례로, Base 객체를 가리키는 포인터는 Derived도 가리킬 수 있는 것입니다. 뭐 별 거 없어요. 인공적인 예를 수없이 만들어 보여드릴 수 있지만 그런 건 의미가 없어 보이고, 어디보자. 실전적이면서도 이해하기 쉬운 예 어디 없나.. 모르겠네요. 나중에 생각나면 다시 답변하로 하고, 그냥 인공적인 걸로 할게요.

class Fruit{};
 
class Apple: public Fruit{};
class Orange: public Fruit{};
 
void give_me_a_fruit(Fruit *fruit){ return; }
// fruit이 구체적으로 어떤 과일인지는 상관 없고 그냥 과일이기만 하면 됨.
 
int main(){
    Apple apple;
    Orange orange;
 
    give_me_a_fruit(&apple); // 그래서 아무 과일이나 던져 줄 수 있음
    give_me_a_fruit(&orange); // 사과든 오랜지든.
 
    return 0;
}
어 음..의 이미지

50퍼센트 정도 납득을 할 수 있게된 것 같습니다
선언과 정의를 잘못 말했네요

아직도 저는 B *Test = new B; 하면 될걸 A *Test = new B 하는 이유를 잘 모르겠습니다.

lalupo20의 이미지

GLObject* a
//이하 GLObject 상속
GLTriangle* b;
GLRectangle* c;
GLCircle* d
 
list<GLObject*> l
list<GLObject*>::iterator obj_iterPos;
 
l.pushback(a);
l.pushback(b);
l.pushback(c);
 
((GLObject*)(*obj_iterPos))->draw();
twinwings의 이미지


클래스의 상속은 크게 두 가지 목적을 가지고 있습니다.
첫 째는 재사용 및 확장이고 두 번째는 다형성입니다.

부모 클래스의 포인터를 이용 하겠다는 말은 재사용성이 아닌, 다형성(polymorphism)을 이용하겠다는 것을 암시합니다.

질문자는 다형성에 대해 이해가 부족하고, 이와 관련된 코드를 보거나 작성해본 경험이 드물어 보입이다. 다형성에 대해서 검색하면 좋은 글 많을 겁니다. 이 부분 공부하시길 바랍니다.

twinwings의 이미지

상속하고 있는 클래스의 소멸자는 대부분 vritual로 정의하여야 합니다. 그렇지 않으면 소멸자가 정적 바인딩 되기 때문에 자식 클래스를 delete하는 경우 자식의 소멸자가 아닌 부모의 소멸자가 호출 될 수 있습니다.

virtual 함수의 본질은, 함수 포인터로서 이 부분 공부하시면 많은 도움이 되리라 생각됩니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.