gpt4 book ai didi

c++从继承链获取对外部成员的访问

转载 作者:行者123 更新时间:2023-11-28 01:39:41 27 4
gpt4 key购买 nike

我有以下设计: - 一个具有 M 类 protected 成员的 A 类。 - 一个 B 类继承自 A 并具有指向 C 类对象的指针 - 一个类 C 需要访问类 A 的成员

class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
M _member;
}

class B : public A {
public:
B(){}
~B(){}
protected:
C* c;
}

class C {
// C needs to have access to _member
}

什么样的设计更适合解决这个问题?

最佳答案

在纯粹的 OO 术语中,允许一个类直接访问另一个类的内部字段是不好的做法。

也就是说,C++ 不是纯粹的 OO 语言,并且确实允许这样做(以及与 OO 的其他重要偏差)。

要允许另一个类访问私有(private)成员,您必须指定该类为友元。然而,友元不会传递给派生类,因此您必须将该类升级为您需要的类型。

这是最简单的解决方案:

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

但是,如前所述,任何从 C 派生的类都无法访问 _member,因为友元不会被继承,因此需要更全面的解决方案:

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;
}

这样一来,从A派生的类都不提供对_member的直接访问,从C派生的类也不提供对_member的直接访问,但是仍然可以通过C的protected API访问成员变量。这也可以防止其他外部对象访问它。

关于c++从继承链获取对外部成员的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47771286/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com