我想要運行的特定功能每當對象被構造,[...它]在轉恰好調用虛函數,我想允許派生類的能力如果他們想要,可以覆
這可以,如果你願意住有兩個限制,可以輕鬆完成:
- 建設者在整個類層次結構必須是非公開的,因而
- 工廠模板類必須用於構造派生類。
這裏,「特定功能」是Base::check
,虛擬功能是Base::method
。
首先,我們建立基類。它必須滿足兩個要求:
- 它必須與
MakeBase
,其檢查類。我假設你想Base::check
方法是私人的,只能在工廠使用。如果它是公開的,當然你不需要MakeBase
。
- 構造函數必須受到保護。
https://github.com/KubaO/stackoverflown/tree/master/questions/imbue-constructor-35658459
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
class Base {
friend class MakeBase;
void check() {
cout << "check()" << endl;
method();
}
protected:
Base() { cout << "Base()" << endl; }
public:
virtual ~Base() {}
virtual void method() {}
};
模板化CRTP工廠從一個基類,與Base
朋友派生,並因此先後獲得了私人檢查方法;它也可以訪問受保護的構造函數以構建任何派生類。
class MakeBase {
protected:
static void check(Base * b) { b->check(); }
};
工廠類可以發出一個可讀的編譯時錯誤消息,如果您不小心使用它不是從Base
派生的類:
template <class C> class Make : public C, MakeBase {
public:
template <typename... Args> Make(Args&&... args) : C(std::forward<Args>(args)...) {
static_assert(std::is_base_of<Base, C>::value,
"Make requires a class derived from Base");
check(this);
}
};
派生類必須有一個受保護的構造:
class Derived : public Base {
int a;
protected:
Derived(int a) : a(a) { cout << "Derived() " << endl; }
void method() override { cout << ">" << a << "<" << endl; }
};
int main()
{
Make<Derived> d(3);
}
輸出:
Base()
Derived()
check()
>3<
如果函數調用是構造派生類所必需的,並且是特定於該類的,那麼聽起來好像應該從派生類的構造函數中調用它。想要從一個技術上還不存在的對象調用方法並不是一個好主意。 –
那麼我想運行的函數是一種運行時驗證程序,以確保它們寫出的派生類符合某些要求。它需要訪問虛擬功能以檢查它們是否正常工作。 –
在這種情況下,@ Jarod42提出的工廠方法可能是您最好的選擇。 –