有没有办法让所有派生类成为彼此的朋友?

时间:2015-07-17 17:05:14

标签: c++ derived-class c++03 friend-class

如果是这样,在什么情况下这可能会有用?

或者(我想是这样的),为什么它绝对没用? (还有哪种方法基本上涵盖了这种友谊提供的能力,但是以更安全,更少泄漏的方式?)

我的情况几乎以为我需要这样的事情。我最终采用了完全不同的设计,使所有的班级成员都保持静态。我现在还好奇。

3 个答案:

答案 0 :(得分:2)

  

有没有办法让所有派生类成为彼此的朋友?

该语言没有提供任何在基类中指定类似内容的机制。您必须在从基类继承的每个类中提供好友声明。

我无法提出任何更积极的建议,因为我不知道你要解决的问题。

在评论中,你说:

  

就我而言,我需要访问同级方法,因此如果BC来自A,我需要从B::foo()致电C::foo() 。在我的例子中,这些类封装了不同的算法(因此我想到了策略模式......)但有时一种算法会使用另一种算法的实质部分。然而,从C派生B似乎不正确,因为CB实际上没有“is-a”关系。

如果CB没有“is-a”关系,但C::foo()需要调用B::foo(),则表明B::foo() B C 1}}只能使用B::foo()C::foo()共有的数据。在这种情况下,应该可以将代码分解为非成员函数,然后在B::foo() ^ | C::foo() <some namespace>::foo() ^ | +-------+---------+ | | B::foo() C::foo() 中使用它。

更改依赖项:

ICollection<ElementId> columnIds = JoinGeometryUtils.GetJoinedElements(doc, beamElement)

#!/usr/bin/python
class Chipsn():

      self.seq = [70, 80, 90, 100, 110]
      self.dict = collections.defaultdict(list)
      self.dict = {v: 0 for v in self.seq}

   def sort_func(self):
      """This is a private method that sorts the values in the list and then calls the 'avg_func' function to calculate and display the average datapoints."""

      self.sortd_datapoints = sorted(self.datapoints, key=lambda i: i[1])
      self.nfp_temp_data = [i[1:2] for i in self.sortd_datapoints]
      self.nfp_pow_data = [i[2:3] for i in self.sortd_datapoints]
      self.sys_pow_data = [i[3:4] for i in self.sortd_datapoints]
      self.core_pow_data = [i[4:5] for i in self.sortd_datapoints]

      self.avg_func(self.nfp_temp_data)
      self.avg_func(self.nfp_pow_data)
      self.avg_func(self.sys_pow_data)
      self.avg_func(self.core_pow_data)


   def avg_func(self, data_array):
      """This is a Private method -> Creates required keys and assign values to it. After this computes the average for the values in corresponding keys."""

      for i in data_array:
         if i[0] in self.dict.keys():
            self.dict[i[0]].append(i[0])
         else:
            (x, success) = self.in_range_func(i[0], self.dict.keys())
            if success:
               self.dict[x] = [i[0]]

      for x in sorted(self.dict.keys()):
         print self.dict[x]


   def in_range_func(self, curtemp, keys):
      """This is a Private method -> It decides the keys for the dictionary array"""      

      for k in keys:
         if (k-5) <= curtemp <= (k+5):
            return (k, True)
      return (curtemp, False) 

答案 1 :(得分:2)

C ++只为您提供两种方式来命名朋友:

friend class C; // a specific class

template <typename T>
friend class S; // friend the class template S

没有办法在那里插入一个元函数,这看起来像是假设:

template <typename T>
friend enable_if_t<std::is_base_of<Base, T>::value, T>;

但是我想如果你对可怕的hackery持开放(这句话应该被解释为从来没有这样做,请上帝不要,但它至少有点有趣),你可以简单地实现所有派生类型作为显式专业化一些模板。

struct Base { ... };

template <typename > class Derived;

struct A_tag { };

template <>
class Derived<A_tag> : Base {
    template <typename T>
    friend class Derived;

    ...
};

using A = Derived<A_tag>;

如果我们为BC等做同样的事情,那么ABC是所有朋友 - 因为在他们真的是Derived<A_tag>Derived<B_tag>Derived<C_tag>,因此朋友类模板语句涵盖了所有这些。

答案 2 :(得分:2)

完全不是friend,但您可以使用Passkey pattern

的某些变体来限制访问权限

如果在基类中创建受保护的内部Passkey类。然后,任何派生类都可以通过要求将密钥作为参数来限制对兄弟姐妹的访问:

class A {
protected:
  class Passkey {};
};

class B : public A {
public:
  void someProtectedFunction(Passkey) {};
};

class C : public A {
public:
  void somePublicFunction() {
    B b;
    b.someProtectedFunction(A::Passkey{});
  }
};

int main() {
  C c;
  c.somePublicFunction();

  B b;
  //b.someProtectedFunction(A::Passkey{});  // error: `class A::Passkey` is protected
}