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 ++虚拟+受保护?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中调用受保护的虚拟方法 [重复]

你会拥有太多的“受保护的虚拟”方法吗?

这。与基地。对于继承的受保护的非虚拟方法?

在派生类中使用来自虚拟基类的受保护 ctor

C/C++代码虚拟化保护 在移动端的应用

从受保护的未选中字段中获取虚拟字段