c++ 에서 상속된 클래스에서 보호멤버는 왜 클래스 접근만 지원

voider의 이미지

제목을 보고는 저도 이해가 안가네요.. ㅡ.ㅡ;

class A {
protected:
  int i;
};
class B : public A {
void Plus(A & a) {
  i += a.i; // <-- 이부분 에서 컴파일 에러
}
void AnotherPlus(B & b) {
  i+= b.i;
}
};

위와 같은 코드에서 왜 기초 클래스의 멤버에 대해 접근을 못할까요?
B 클래스 관점에서 봤을땐 A클래스나 B클래스나 마찬가지 아닌가요?

자바도 이런식이었는지 기억이 가물가물한데 너무 지나친 제한인것 같다는 생각이 드네요.
아니면 무슨 다른 이유라도 있어서 막은건가요?

progcom의 이미지

B 클래스가 A 클래스를 상속하고는 있지만, 외부에서 만들어진 a와는 전혀 관계가 없는 것이니까요. protected의 정상적인 작동입니다.
클래스 이름과 인스턴스를 착각하시면 안됩니다. :)

zelon의 이미지

그런가요? 하지만 다음과 같은 코드는 컴파일 에러가 안 나는데요? ^^;;;

class A
{
public:
	void printA(A * p)
	{
		cout << p->k << endl;
	}

private:
	int k;
};

A * pA = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
	pA = new A();

	A kkk;
	kkk.printA(pA);

	return 0;
}

위의 코드를 보면 protected 를 통해서 상속받은 건 일반적인 private 와는 결국 다른건가요? 보통 책에 보면 부모의 protected 는 private 으로 상속된다라고 되어있지만 컴파일러의 해석은 뭔가 다른가보군요.

-----------------------------------------------------------------------
GPL 오픈소스 윈도우용 이미지 뷰어 ZViewer - http://zviewer.wimy.com
블로그 : http://blog.wimy.com

doldori의 이미지

지금 나오는 에러는 착각하기 쉬운 것인데, 두 클래스가 상속 관계에 있긴 하지만
엄연히 다른 클래스입니다. 따라서 B 클래스의 멤버에서 A 개체의 protected
멤버에는 접근할 수 없습니다. 그러나 B 개체의 protected 멤버에는 접근할
수 있습니다. 그래서 AnotherPlus()에서는 에러가 나지 않는 것이죠.
관점에 따라 너무 지나친 제약이 아니냐고 할 수도 있는데 이를 허용하게 되면
좀 미묘한 문제가 발생할 수도 있기 때문입니다. 예를 들어 A를 상속받는 C
클래스가 있다고 할 때 B와 C가 서로의 protected 멤버에 접근하는 것은
논리적으로 부당하지 않습니까?

wafe의 이미지

"테스트주도개발"이라는 책을 보면서 JAVA로 나온 예제를 C#으로 따라해보고 있다가 C#과 JAVA에서 protected의 해석이 다르다는 걸 발견하고는 C++에서는 어떤지 시험해 봤더니 C++과 C#은 protected를 동일하게 해석하고, JAVA는 좀 다르더군요.

위에 C++로 올리신 코드를 JAVA로 바꿔서 해보니 문제없이 잘 돌아갑니다.

public class test2 {
    public static void main(String[] args) {
        B b1 = new B();
        A a1 = new A();

        b1.plus(a1);
        b1.printi();

        b1.plus(b1);
        b1.printi();
    }
}

class A {
    protected int i = 1;
}

class B extends A {
    public void plus(A _a) {
        i += _a.i;
    }

    public void plus(B _b) {
        i += _b.i;
    }

    public void printi() {
        System.out.println(i);
    }
}

Heejoon Lee

atie의 이미지

자바에서 protected scope을 정확히 테스트하려면, 다른 package에서 해야 합니다. 이 글을 다시 한번 보시죠.

----
I paint objects as I think them, not as I see them.
atie's minipage

댓글 달기

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