C++ 상속과 객체 포인터에 관해

익명 사용자의 이미지

야매로 C++ 공부하고 있는 사람입니다.
지금 상속 파트를 공부하고 있어서 코드 이래저래 짜보고 있는데 궁금한 점이 있습니다.

가령 메인이 되는 소스가 있고, B 클래스와 C 클래스가 있습니다.
B 클래스는 C 클래스의 부모입니다.
이 때 B클래스에서 protected 속성의 변수를 자신의 public 속성의 함수로 특정 값을 넣고, 메인이 되는 소스에서는 B클래스와 C클래스를 각각 객체 포인터로 선언하면 C클래스에서 B클래스의 해당 변수가 변경된 값이 아닌 그저 텅 빈 값이더군요.

이유는 별도의 객체로 돌아가기 때문인 것은 알겠습니다.
이 경우 객체 포인터간에 부모 클래스의 protected 변수의 값을 공유할 방법은 없는지, 그리고 만약 없다면 의도한 바를 할 수 있는 다른 방법이 있는지 궁금합니다.
예시에서야 값이 하나라 손쉽게 꼼수 쓸 수 있지만, 실전은 변경해야 하는 값이 많다보니 녹록지 않더군요.

보다 나은 이해를 위해 예시 코드를 아래에 첨부합니다.

#include <iostream>
using namespace std;
 
class B
{
protected:
	int i;
public:
	B() {}
	void Test()
        {
		i = 5;
        }
	~B() {}
};
 
class C : public B
{
public:
	C() {}
	void Check()
	{
		cout << i;
	}
	~C() {}
};
 
//void C::
 
void main()
{
	B *TestB = new B;
	C *TestC = new C;
	TestB->Test();
	TestC->Check();   //쓰레기값 출력. i에 5가 안 들어가 있음
}
jick의 이미지

상속이냐 아니냐는 중요하지 않고, 하나의 클래스를 사용하는 모든 객체가 같은 멤버 변수를 공유하게 하고 싶으면 이렇게 하면 됩니다.

class B {
  protected:
    static int i;
  ......
};

다만 이렇게 선언된 i는 B 안에 선언이 되었다고는 해도 별개로 존재하는 *단 하나의* 변수이므로 어딘가 (헤더 파일이 아닌) 소스 파일에서 정의를 해줘야 합니다:

int B::i;

그런데 제가 보기엔 뭔가 멤버 변수의 의미를 근본적으로 헷갈리고 계신 게 아닌가 싶은데요. C가 B를 상속하면 각각의 C 객체 안에 B 객체가 들어있는 거죠, 너무나 당연히 서로 다른 C 객체가 같은 B 객체를 공유하고 있지는 않습니다. 원하는 동작이 뭔지 잘 생각해 보시는 게...

익명 사용자의 이미지

1. 뭔가 개념의 혼동이 있는 것 같군요.

B 클래스, C 클래스, B 클래스의 인스턴스, C 클래스의 인스턴스를 잘 구분하셔야 됩니다.
물론 public 상속 관계에 의해 C 클래스의 인스턴스는 B 클래스의 인스턴스입니다.

(1) non-static member variable은 인스턴스마다 하나씩 생깁니다. 클래스마다 하나씩 생기는 게 아닙니다.
클래스마다 하나씩 생기는 member variable을 만들고 싶다면 위 jick님의 답변을 참고하여 static member를 만드시면 됩니다.

(2) 주어진 코드에서 TestB와 TestC가 가리키는 인스턴스는 서로 독립적입니다. 전혀 다른 인스턴스라는 말입니다.
TestC가 가리키는 인스턴스의 "클래스 B 부분"을 얻고 싶다면 B *TestC2 = TestC; 하면 됩니다.

익명 사용자의 이미지

어우 그렇군요 두분 다 답변 감사합니다 개념쪽을 다시 펼쳐봐야겠습니다
잘못하면 그릇된 지식을 가지고 넘어갈 뻔한 부분이었네요

댓글 달기

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