簡體   English   中英

派生類如何使用基類的受保護成員?

[英]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";
}

如果otherB類的一個實例,那就沒問題了。 但該函數希望適用於任何類型的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)

在你的情況下,你可以將otherconst B& (通過static_castreinterpret_cast )但你不知道other實例是否是B類型。 有了這個輸入值,人們讀取代碼就會假定other類型是B並且可以插入導致讀取/寫入“隨機”內存的代碼。

考慮到B類具有另一個value_Bother類型為C 使用static_cast<const B&>(other).value_B是未定義的行為。

暫無
暫無

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

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