순수 OO 용어에서 클래스가 다른 클래스의 내부 필드에 직접 액세스하도록 허용하는 것은 좋지 않습니다.
즉, C++은 순수 OO 언어가 아니며이를 (OO의 다른 중요한 편차 중에서도) 허용합니다.
개인 멤버에 다른 클래스에 대한 액세스를 허용하려면 해당 클래스를 친구로 지정해야합니다. 그러나 우정은 파생 된 클래스에 전달되지 않으므로 클래스를 필요한 유형으로 업 캐스팅해야합니다.
이 당신의 간단한 솔루션입니다 :
같은 방법으로
class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
friend class C;
M _member;
}
class B : public A {
public:
B(){ c = new C(this); } // this call will cast the B* to an A* (important)
~B(){ delete c;}
protected:
C* c;
}
class C {
public:
C(A* a) { _a->_member = new M(); } //Now C can directly access _member in A
}
, A
에서 파생 된 객체가 A*
로 다시 돌아 서서 _member
에 액세스 할 수 있습니다.
그러나 앞서 언급 한 바와 같이, 우정 상속하지 않는 한, _member
에 액세스 할 수 없습니다 C에서 파생 된 모든 클래스, 그래서 더욱 포괄적 인 솔루션이 필요합니다 :이 방법으로
class M {
public:
void Foo() { printf("Foo called\n"); }
};
class A {
M* m;
friend class C;
public:
A():m(0) { ; }
};
class B :public A {
int id;
public:
B() { id = 0; }
};
class C {
public:
C() { _a = 0; }
C(A* a) { _a = a; }
protected:
M* getM() { return _a->m; }
void setM(M* m_) { _a->m = m_; }
private:
A* _a;
};
class D : public C {
public:
D(B* b): C(b) {
}
void Foo() {
setM(new M());
getM()->Foo();
delete getM();
setM(nullptr);
}
};
int main()
{
B* b = new B();
D d(b);
d.Foo();
delete b;
getchar();
return 0;
}
, 아니 클래스는 파생 없습니다 from A는 _member에 대한 직접 액세스를 제공하고 C에서 파생 된 클래스는 직접 액세스 할 수 없지만 C의 보호 된 API를 통해 멤버 변수에 계속 액세스 할 수 있습니다. 이것은 또한 다른 외부 객체가 액세스하는 것을 방지합니다.
일반적인 답은 _member에 대한 액세스를 관리하는 것입니다. setter 및 getter 메소드 C가 A 또는 B와 관계가 없도록 상속 체인이 구성되므로 "친구"는 코드 전체에서 액세스 패턴을 오염시키고 다른 의도하지 않은 액세스 권한을 부여 할 수 있습니다. – StarShine