C ++虚拟+受保护?
Posted
技术标签:
【中文标题】C ++虚拟+受保护?【英文标题】:C++ virtual + protected? 【发布时间】:2011-06-01 13:14:26 【问题描述】:在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚拟方法 Visit。 我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”函数。
我有类似的东西,但它告诉我 B 无法访问 A 的受保护成员!但是 B 也是 A :-P
那么,我该怎么办?
class A
protected:
virtual Visit(...);
class B : public class A
protected:
vector<A*> childs;
Visit(...);
B::Visit(...)
foreach(A* a in childs)
a->Visit(...);
谢谢
【问题讨论】:
我无法从您的代码中看出 B 是 A 的子类。 你确定你在写 C++ 吗?在 C++ 中,没有 foreach 关键字。foreach(A* a in childs)
是什么?您的代码中是否有一些宏没有告诉我们。
@Charles 这是伪代码,就像访问必须返回一些东西,而你不能只是传递...
@CashCow:谢谢,下次我会更直接。
【参考方案1】:
您可以使用自己的对象访问受保护的成员,但不能使用替代对象访问受保护的成员,除非它也是您的类(不仅仅是基类)。
有一种变通方法,就像有一种变通方法不继承友谊一样。
在这个例子的任何情况下:
class A
protected:
virtual void Visit(...);
void visitOther( A& other, ... )
other.Visit(...);
;
class B : public A
Visit(...);
vector<A*> childs;
;
B::Visit(...)
BOOST_FOREACH( a, childs )
visitOther( *a, ... );
【讨论】:
是的,我考虑过将其设为静态。 这就是为什么 c++ 是完全蹩脚的头痛。他们甚至搞砸了这个简单的概念。不让以这种方式访问受保护的成员有什么意义?为什么它会受到保护?【参考方案2】:只要让 B 成为 A 的朋友:
class A
protected:
virtual void Visit();
friend class B;
;
class B : public A
protected:
virtual void Visit();
;
【讨论】:
-1 打破了封装,如果我也有一个从 A 派生的 C,但同样的问题怎么办? "friend" 关键字存在,所以当你知道你在做什么时使用它也不错:这里没有提到 C 类,所以你想让场景复杂化什么?【参考方案3】:虚函数的本质正是你要逃避的。 这里
foreach (A * in the Childs)
a-> Visit (...);
所有a
都会调用它对应的访问函数。
没有必要公开从 A 派生,你应该使用 protected。
A
中的Visit函数不是虚函数,并做一个受保护的构造函数,
通过继承(以及朋友和 hax)限制实例化。
如果您提供更多详细信息,我们也可以提供更多帮助。
编辑 1:如果您正在玩虚拟,请不要忘记虚拟析构函数。
编辑 2: 试试这个:
foreach (A * in the Childs)
a->A::Visit(...);
【讨论】:
【参考方案4】:听听编译器告诉你你的设计被搞砸了,不要再假装你知道得更好。公开访问。更好的是,让它成为非虚拟的:
struct A
void Visit() impl_visit();
private:
virtual void impl_visit();
;
struct B : A
private:
Vector<A*> childs;
void impl_visit()
...
foreach child in childs child->Visit();
...
;
哦,当你在请求委员会添加漂亮的“foreach/in”语法时。 [我是认真的,他们正在寻找使 C++ 更易于使用的方法!]
【讨论】:
【参考方案5】:在“示例”中已更正。现在 B 是 A 的子类。
【讨论】:
以上是关于C ++虚拟+受保护?的主要内容,如果未能解决你的问题,请参考以下文章