[英]How can a derived class use a protected member of the base class?
假設基類A
定義了受保護的成員。 派生類B
使用此成員。
class A
{
public:
A(int v) : value(v) { }
protected:
int value;
};
class B : public A
{
public:
B(int v) : A(v) { }
void print() const;
void compare_and_print(const A& other) const;
};
函數B::print
只取當前成員的值並打印出來:
void B::print() const
{
std::cout << "Value: " << value << "\n";
}
另一個成員函數B::compare_and_print
采用A
的實例,檢查它們的值並打印兩者的最大值:
void B::compare_and_print(const A& other) const
{
auto max_value = std::max(value, other.value);
std::cout << "Max value: " << max_value << "\n";
}
如果other
是B
類的一個實例,那就沒問題了。 但該函數希望適用於任何類型的A
實例。 遺憾的是,這不會編譯。 這就是鏗鏘說的:
test.cpp:27:42: error: 'value' is a protected member of 'A'
auto max_value = std::max(value, other.value);
^
test.cpp:9:7: note: can only access this member on an object of type 'B'
int value;
^
1 error generated.
這種限制聽起來與我相反。 但是,我不會對C ++標准提出異議(我對這個決定背后的理由感興趣)。
我的問題是在我的項目中我確實有這種用例:派生類有一個方法,它接受基類的一個實例,需要訪問接收對象的受保護成員。
最簡單的解決方案是我當前實現的解決方案,是將一個公共成員函數添加到基類,該基類返回受保護的成員。 這個解決方案並不能完全滿足我,因為我想避免以這種方式導出成員。
如何通過派生類啟用基類'受保護成員的使用而不通過API導出成員?
編輯:一些相關的問題是:
我想要的答案是解釋這個問題的設計模式的解釋,而不將受保護的成員暴露給外部代碼( 外部意味着代碼不是定義這些類的框架的一部分)。
我承認,這種模式可能不存在。
實際上有一個使用成員指針的漏洞(沒有強制轉換,沒有復制):
void B::compare_and_print(const A& other) const
{
auto max_value = std::max(value, other.*(&B::value));
std::cout << "Max value: " << max_value << "\n";
}
您可以使用幫助程序結構繞過protected:
struct A_Helper : public A
{
static int GetProtectedValue(const A & a)
{
return static_cast<const A_Helper&>(a).Value;
}
};
你可以在任何地方使用它來獲得它A_Helper::GetProtectedValue(a)
在你的情況下,你可以將other
為const B&
(通過static_cast
或reinterpret_cast
)但你不知道other
實例是否是B
類型。 有了這個輸入值,人們讀取代碼就會假定other
類型是B
並且可以插入導致讀取/寫入“隨機”內存的代碼。
考慮到B
類具有另一個value_B
而other
類型為C
。 使用static_cast<const B&>(other).value_B
是未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.