簡體   English   中英

如何從派生類到基類ptr訪問受保護的基類函數

[英]How to access protected base class function, from derived class through base class ptr

我有抽象類A,從中繼承了許多類。 在派生類中,我試圖在A槽A指針中訪問受保護的函數。 但是我得到一個編譯器錯誤。

class A
{
   protected:
        virtual  void f()=0;
};

class D : public A
{
    public:
         D(A* aa) :mAPtr(aa){}
         void g();

    protected:
         virtual void f();

    private:
      A* mAPtr; // ptr shows to some derived class instance
};

void D::f(){  }


void D::g()
{
   mAPtr->f();
}

編譯器錯誤說:無法訪問在類A中聲明的受保護成員A :: f。

如果我將mAPtr聲明為D *,則A *一切都會編譯。 我不明白為什么會這樣。

依靠private訪問對相同類型的不相關實例起作用。

依賴protected訪問可用於相同類型(以及更多派生類型)的不相關實例。

然而,依賴於protected訪問不會在基類的實例無關的工作。

[n3290: 11.5/1]: 派生類 朋友或成員函數引用 基類 的受保護的非靜態成員函數或受保護的非靜態數據成員 ,除了第11節中所述的訪問檢查之外,還將進行訪問檢查。當形成指向成員(5.3.1)的指針時, 訪問必須通過指向,引用或引用派生類本身(或從該類派生的任何類) (5.2.5)的對象的對象來實現 如果訪問要形成指向成員的指針,則嵌套名稱說明符應命名派生類(或從該類派生的任何類)。

所以D或從D衍生而來的東西,而不是A

盡管如此,關於C ++的一種經常被質疑的怪異之處仍然是旨在避免陷阱。 畢竟,您不知道*mAPtr 真正具有什么類型。

包含受保護節的類意味着該類允許派生類以其選擇的任何方式(在受保護的接口允許的范圍內)操縱其基類。

D類對象可以操縱自己的A部分。 這樣說來,他們可能想要保持一些不變性。

假設存在(或將來還會有!)另一個類E,它也繼承自A。類E對象也可以操縱自己的A部分,並且它們可以強制執行不同的不變式。

現在,如果允許D類對象操作任何對象的A部分,則不能確保不變性。 AD對象可能會對E對象的A部分造成破壞,從而破壞該E對象。 這就是為什么不允許這樣做。


但是,如果您確實願意,也許可以通過一個朋友函數來調用A :: f而不暴露給所有人。

class A;

namespace detail
{
   void call_f(A*);
}

class A
{
   friend void detail::call_f(A*);
private:
   virtual void f() = 0;
};

namespace detail
{
   void call_f(A* a) { a->f(); }
}

class D: public A
{
public: 
    void g() { detail::call_f(mAPtr); }
private: 
    void f() {}
    A* mAPtr;
};

這依賴於對用戶進行嚴格訓練,以使其不進入名稱空間,該名稱空間清楚地表明其包含實現細節。

您忘記了使用; 課后聲明:

class A
{
   protected:
       virtual  void f()=0;
};

class D : public A
{
    public:
        void g();

    protected:
        void f();

    private:
       A* mAPtr; // ptr shows to some derived class instance
};

此外,您不需要存儲基類指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM