다중상속과 관련해서 어떻게 하시겠습니까?

레모네이드의 이미지

방법1. 다이아몬드 상속시 이름 중복 해결방법

#include <iostream>
class original {
private:
	virtual void function()=0;
	friend void somemodule(original* po);
};
 
void somemodule( original* po) {
	po->function();
}
 
class other : public original {   // virtual 상속이 아닙니다.
private:
	virtual void function () {
		otherfunction();
	}
	virtual void otherfunction()= 0;
};
 
class another : public original {  // virtual 상속이 아닙니다.
private:
	virtual void function () {
		anotherfunction();
	}
	virtual void anotherfunction() = 0;
};
 
class finalclass : public other , public another {
	virtual void otherfunction(){
		prntf("주저리주러리\n")
	}
	virtual void anotherfunction(){
		prntf("궁시렁궁시렁\n");
	}
};
 
void main() {
	finalclass fc;
	somemodule( (other*)(&fc) );  // static_cast로 other* 캐스트
	somemodule( (another*)(&fc) ); // static_cast로 another* 캐스트
}

방법2.

#include <iostream>
class original {
private:
	virtual void function()=0;
	friend void somemodule(original* po);
};
 
void somemodule( original* po) {
	po->function();
}
 
class other {   // original로부터 상속받지 않았습니다.
private:
	virtual void otherfunction()= 0;
};
 
class another {   // original로부터 상속받지 않았습니다.
private:
	virtual void anotherfunction() = 0;
};
 
class finalclass : public other , public another {
	virtual void otherfunction(){
		prntf("주저리주러리\n")
	}
	virtual void anotherfunction(){
		prntf("궁시렁궁시렁\n");
	}
};
 
void main() {
	finalclass fc;
	somemodule( (original*)(other*)(&fc) ) );  // static_cast로 other* , reinterpet로 original* 캐스트
	somemodule( (original*)(another*)(&fc) ) );// static_cast로 another* , reinterpet로 original* 캐스트
}

여기 편집결과가 에서 c++스타일의 캐스팅이 이상하게 출력되서 c스타일로 그냥 뒀습니다..

먼저 somemodule의 제작자는 other와 another 그리고 finalclass 이런 클래스가 올것이라는것을
전혀 알지 못하는 상태라고 가정합니다. 그리고 original 클래스형이라면 function을 호출할수 있는 기능을 가지고 있습니다.
그리고 방법2에서는 상속을 받지는 않지만, 무조건 original과 그 형태를 일치시키는 방법입니다.

이 두가지 방법 모두 컴파일 결과는 동일하다고 생각합니다...
방법1의 경우 중간 경유하는 함수가 하나더 있어서 성능이 떨어질것으로 생각되지만, original과 other/another의 의미상 결합이 강하고,
그리고, 방법1은 The C++ Programing Language(비야네)에서 소개하는 방법이기도 합니다.
방법2의 경우 중간 경유하는 함수가 없기에 성능은 좋을것이나, original과 other/another의 의미상 결합이 약합니다.
그리고, 방법2는 C++의 언어와 컴파일러의 특성상 허락되는 방법이라 생각되고, reinterpet_cast연산자의 존재이유라고도 생각됩니다...

어떤것을 선택하시겠습니까?
방법2의 경우 프로그램의 안전성에 문제가 될 소지가 있을것 같습니까?

semmal의 이미지

그렇게 할 거라면 하나의 클래스로 부터 인터페이스만 상속하고 구현은 다른 하나는 delegation하는게 맞을 것 같네요.

두번째 방법을 쓸거라면 두 개의 클래스로부터 인터페이스 상속받고 구현은 original을 delegation하든지요.

------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

김일영의 이미지

function과 other/another간의 명시적인 관계가 없는데
저런 호출이 된다곤 하더라도
실제 프로젝트에서 일일이 저런걸 기억해가며 쓰기엔 너무 빡센 것 같네요.
에러 나면 디버깅은 죽음이겠죠...T.T

댓글 달기

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