【问题标题】:Friendship vs inheritance友谊VS继承
【发布时间】:2011-06-16 19:34:35
【问题描述】:

我有下面的类层次结构。基本上,我想在 Foo 和 CComplexMat 类之间建立“has-a”关系,即 Foo 类“has-a”CComplexMat。 据我所知,类的privateprotected 成员无法从定义它们的类外部访问。

但是,允许其他类访问此类成员有两种可能性。 第一个是使用friend 类。我可以在class CComplexMat<T> 的声明中添加一行friend class Foo<T>;,这样 Foo<T> 可以访问class CComplexMat<T>protectedprivate 成员。

第二种可能是使用inheritance,这是我在示例中选择的解决方案。在这种情况下,我正在考虑使用public 继承,以便 publicprotected 的成员 class CComplexMat<T> 都可以在类 Foo<T> 中访问。但是,显示以下错误:

error: ‘CMatrix<float>* CComplexMatrix<float>::m_pReal’ is protected

error: within this context

  1. 我想知道是否有人可以阐明这个错误?
  2. 在哪些情况下“友情”或“遗产”更合适?
template <class T>
class CMatrix{
    public:
     ...
        CMatrix<T> & operator = (const CMatrix<T> &);
        T & operator()(int, int, int);
        T operator()(int, int, int) const;
     ...
    private:
       T *** pData;
       int rows, cols, ch;
};

template <class T>
class CComplexMat: public CMatrix<T>{
    public:
    ...
    protected:
        CMatrix<T> *pReal;
        CMatrix<T> *pImag;
};

template <class T>
class Foo: public CComplexMat<T>{
    public:
        ...
        void doSomething(){
           ...
           CMatrix<T>*pTmp = pComplex->pReal; // error here.
           ...
        }
    ...
    private:
        CComplexMat<T> * pComplex;
    ...
};

【问题讨论】:

    标签: c++ inheritance friend protected access-control


    【解决方案1】:

    您正在访问 Foo 类中 CComplexMat 的局部变量,而不是仅访问父类以获取 pReal 的值。

    tutorial 打破了 C++ 中友谊和继承之间的区别。
    注意他们如何直接访问父类的成员变量,而不需要父类类型的本地成员。这可能是您在示例中想要做的。

    【讨论】:

      【解决方案2】:

      您无法从类外部访问受保护成员,即使尝试访问的类是包含受保护成员的类的子类。

      在您的示例中,如果 pComplex 将指向 Foo 类型的对象,那么您可以按照您尝试的方式访问 pReal。

      【讨论】:

        【解决方案3】:

        根据关于访问派生类中受保护成员的 C++ 标准 (11.5)

        除了形成指向成员的指针(5.3.1)外,访问必须通过 指向派生类本身(或从该类派生的任何类)的指针、引用或对象

        您正在尝试通过基类访问 pReal。

        让 Foo 成为 CComplexMat 的朋友以访问它的成员。

        【讨论】:

          【解决方案4】:

          继承只能用于“is-a”关系。在我看来 CComplexMat&lt;T&gt; 有两个 CMatrix&lt;T&gt; 成员,但它不是“是”CMatrix&lt;T&gt; 的情况。与FooCComplexMat&lt;T&gt; 进行类似处理。

          所以继承几乎肯定不是正确的解决方案。剩下的:

          • 使用friend 允许密切相关的类之间进行访问。
          • 使用公共访问器方法允许类的用户以有限的方式“获取”私有成员。

          例如,CComplexMat&lt;T&gt; 可能应该有用于实部和虚部的私有成员,但也应该有一些访问器,例如:

          public:
              const CMatrix<T>& realPart() const;
              CMatrix<T>& realPart();
              const CMatrix<T>& imagPart() const;
              CMatrix<T>& imagPart();
          

          【讨论】:

          • +1,这个建议你只比我快 30 秒
          • 感谢您的建议。对于 getter,const .... const; 方法意味着对象的内容不会被修改。另一个吸气剂呢?在这种情况下,我在CMatrix&lt;T&gt; 中重载了operator(),我可以将它用作CComplexMatrix 中的l-value,例如(*this-&gt;m_pReal)(y,x,ch)=something?
          • 是的,CComplexMatrix&lt;T&gt; 中的代码将能够执行(*this-&gt;mpReal)(y,x,ch) = expr(假设operator() 返回T&amp;)。只有当complexMat 不是const 时,其他代码才能执行complexMat.realPart()(y,x,ch) = expr
          • 对于这两种类型的getter,我只需要返回指向私有成员的指针,对吧?
          • @Javier 是的。 (或者return *pReal;,如果成员仍然是一个指针并且函数返回一个引用。)
          猜你喜欢
          • 2013-10-10
          • 1970-01-01
          • 2011-11-19
          • 1970-01-01
          • 2016-05-04
          • 2010-10-10
          • 2019-08-19
          • 2011-09-28
          • 1970-01-01
          相关资源
          最近更新 更多