[英]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.