[완료] c++ 다중상속에 대해서 질문드립니다.

hwayak의 이미지

class Father {
    ...
};
 
class Mother {
    ...
};
 
class Son : public Father, public Mother {
    ...
};
 
 
Son *s = new Son();
Father *f = s;
Mother *m = s;

위 코드에서 저는 이전까지 포인터 s, f, m이 모두 같은 값을 가질것이라 생각하고 있었습니다. 다시 말하면 모두 같은 메모리 주소값을 가질것이라 말이죠.
하지만 오늘 s, f, m을 직접 출력해본 결과, 값이 모두 같지 않더군요..

어떤 이유로 이렇게 되는 건지 알려주세요.
설명이 복잡하다면... 참조할 만한 웹페이지나 서적 추천 부탁드립니다.

레모네이드의 이미지

class Father
{
    int a;
    int b;
};
 
class Mother
{
    int c;
};
 
class Son : public Father, public Mother
{
    int d;
};
 
Son *s = new Son();
Father *f = s;
Mother *m = s;

이 경우에 멤버 데이터들은 메모리에 다음 순서로 저장됨니다.

[ [ Father::a , Father::b ] , [ Mother::c ] , Son::d ]

(void*)s == (void*)&s->a 는 참입니다.
(void*)f == (void*)&s->a 는 참입니다.
(void*)m == (void*)&s->c 는 참입니다.

s로 엑세스 할 수 있는 메모리는
[ Father::a , Father::b , Mother::c , Son::d ] 로서 모두 엑세스 가능합니다.
f로 엑세스 할 수 있는 메모리는
[ Father::a , Father::b ] 로 Father에 속하는것만 엑세스 가능합니다.
m으로 엑세스 할 수 있는 메모리는
[ Mother::c ] 로 Mother에 속하는것만 엑세스 가능합니다.

부모 클래스의 포인터로 형변환하는것에 해당하는것 입니다.... 님 코드에서는 묵시적으로 static_cast 입니다.

f의 경우에는 주소값이 s와 동일하지만, m은 다릅니다.

캐스팅 관련한 문서를 찾아보시면 되겠습니다.

만약 님의 생각처럼 모두 같은 주소가 될려면

Son *s = new Son();
Father *f = reinterpret_cast< Father* >( s );  // Father *f = (Father*)(void*)( s ); 와 같은뜻
Mother *m = reinterpret_cast< Mother* >( s );  // Mother *m = (Mother*)(void*)( s ); 와 같은뜻

와 같이 하면 되겠지만 이것은 원하지 않는 동작을 초래할 것입니다.
만약 이처럼 해서 같은주소가 된다면
s를 통해서 멤버를 엑세스 하는 경우 정상.
f를 통해서 멤버를 엑세스 하는 경우 정상.
m을 통해서 멤버를 엑세스 하는 경우 비정상 의 결과를 초래합니다.
m->d 를 사용하는 경우 s->d를 엑세스하는것이 아니라 s->a를 엑세스하게 됩니다..
원하지 않는 결과지요.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.