[英]Force derived class to implement a private method
有沒有辦法,我可以強制派生類通過私有函數實現接口。 我想要的是以下內容。
class base{
private:
virtual void do_something() = 0; // This can be private/public/protected
};
派生類必須提供非公開的do_something()
實現。 可以猜到,我的目的是使用戶實現一個函數,但要確保基類是調用該函數的class derived : public base{...}
,並且確保class derived : public base{...}
的對象是class derived : public base{...}
曾經無法單獨調用do_something()
嗎?
編輯:只是想添加, class derived : base
的class derived : base
將由用戶而不是我編寫。 用例是確保調用do_something()時基類的功能得到控制。
TL; DR: 否 。
特定
class base {
private:
virtual void do_something() = 0;
};
您不能強制派生類將do_something
實現為私有。 以下是合法的:
struct derived : base {
void do_something() { ... } // public
};
即使您可以強制將其私有,一個類也可以始終調用其自己的私有方法。 這與您的要求“ 與class derived : public base{...}
的對象class derived : public base{...}
將永遠無法自行調用do_something()
” do_something()
。
即使您可以強制派生類實現無法調用的方法,它們仍然可以像這樣解決:
struct derived2 : base {
void do_something_impl() { .... }
private:
void do_something() { do_something_impl(); }
};
現在,他們可以直接調用do_something_impl()
。
這個想法是,您可能需要派生類在構造函數調用中傳遞函數對象,而不是將do_something
聲明為類成員。 但這是丑陋的-我寧願放棄對“無法從派生調用”的要求,並使用protected
。
#include <functional>
#include <iostream>
class base {
public:
base(std::function<void()> do_something) : _do_something(do_something) {}
void act() {
_do_something();
}
private:
std::function<void()> _do_something;
};
class derived : public base {
public:
derived() : base([&]{std::cout << "impl: " << prop1 << ", " << prop2 << std::endl;}) {}
private:
int prop1;
int prop2;
};
int main(int argc, char* argv[]) {
derived d;
d.act();
return 0;
}
你不能那樣做。
請參閱@melpomene的不錯答案。
如果問題在於引用派生類的對象可以公開訪問,則可以執行以下操作:
class base {
private:
virtual void do_something() = 0;
};
template<typename T>
class intermediate: public base, private T {
void do_something() override {
T::do_something();
}
};
class derived {
public:
void do_something() { }
};
int main() {
auto *d = new intermediate<derived>{};
base *b = d;
// not allowed, it's private
// d->do_somerhing();
// b->do_something();
}
在特定限制內,您甚至可以模擬繼承的數據成員 (我知道,它們根本不是繼承的,但是朋友可以在這里提供幫助):
template<typename T>
class intermediate: public base, private T {
friend T;
void do_something() override {
T::do_something(*this);
}
private:
int foo;
};
class derived {
public:
void do_something(intermediate<derived> &ref) {
ref.foo = 42;
}
};
派生類無權訪問基類的private
成員。 如果派生類必須重寫do_something()
,則應對其進行“保護”:
class base
{
protected:
virtual void do_something() = 0;
};
如果do_something()
必須是private
,則應聲明一個protected
方法,該方法可以do_something()
調用並且派生類將其覆蓋。 特別是在do_something()
需要做其他事情時,派生類不應重寫。
class base
{
private:
void do_something()
{
//...
actually_do_something();
//...
}
protected:
virtual void actually_do_something() = 0;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.