我有一個樹類樹,我希望能夠以不同的方式構建它。 build()函數將在Tree的構造函數中調用。課堂上的設計問題和功能
結果在空間和數據結構方面將完全相同,但構建樹的方式會有所不同(每個元素將放置在哪個節點/葉中)。手前已知節點和葉子的數量。
但是,build()具有特定的原型。我希望用戶只要看一下interface
並知道他必須實施什麼。
所以,我正在考慮去與template
。在編寫代碼之後,我注意到樹的用戶沒有任何接口來查看build()的原型。當然,我可以寫在文檔中或讓他/她面對編譯錯誤,但這不是一個好主意,恕我直言。
在這種情況下,用戶會做:
Tree<SplitClass> tree; // ideal, if I could somehow notify him for the prototype
於是,我想到了abstract
類和(pure) virtual methods
。再次,這工作,但現在用戶必須做這樣的事情:
Base* a = new SplitClass;
Tree(a);
在這裏,我不喜歡,是用戶所要做的使用new
和用戶可能不是那麼好節目。而且,用戶不能立即執行,例如template
。
最後,我嘗試了一個function pointer
,它可以工作,但不知道接口。
當然,還有一種解決方案是在其他文件中聲明和定義分割函數幷包含它們。
[編輯]
只是爲了定義一個函數(該項目很重要的),應該創建一個類的事實,是一個壞主意?
[EDIT.2]
構建的原型()只需要std::vector
和一些size_t
變量。在那個階段,我只是在構建這棵樹,所以我沒有任何有關它如何在以後使用的例子。
[EDIT.3]
最小工作實例,它使用了template
。此外,關鍵字virtual
也發揮作用。
這將起作用,但用戶可能實現他自己的一個類,它不會從Base
繼承並通過類Calc
。我不希望他能夠做到這一點。
Calc
是Tree
這個類我在實際項目中有A
和B
這個分裂類。
#include <iostream>
template<class Operation>
class Calc {
public:
Calc(int arg) :
a(arg) {
Operation o(a, 10);
o.add(a);
}
void print() {
std::cout << a << "\n";
}
private:
int a;
};
class Base {
protected:
virtual void add(int& a) = 0;
};
class A: public Base {
public:
A(int& a, int c) {
a = a + c;
}
virtual void add(int& a) {
a += 100;
}
};
class B: public Base {
public:
B(int& a, int c) {
a = a - c;
}
virtual void add(int& a) {
a += 100000;
}
};
int main() {
Calc<A> a(2);
a.print();
Calc<B> b(2);
b.print();
return 0;
}
[編輯。4]
因爲,沒有其他建議,這是我應該從我已經有的人應該遵循的嗎?最好的選擇,根據OOP
「規則」。
我的目標不僅是做出設計決定,而且還要接受教育,其中一個方面就是要走在OOP
世界。
[EDIT.5]
而現在,我覺得這兩個分裂類,應該採取不同數量的參數(多了一個第二個!)。
如果您認爲這個問題不具有建設性或廣泛,讓我知道,我會刪除它。
所以用戶'實現或SplitClass'其他一些類/函數,然後把它傳遞給樹的構造,以建立樹?你能告訴我們更多的例子,以及這個類/函數是如何使用的? – dyp
@dyp確切!我沒有任何其他的小例子。我將編輯原型的樣子。我正處於樹木建設的階段,所以現在只有創作才能發揮作用。我想要一個簡單的方法來構建樹(就像一個用'template'),但不知何故,我想構建()被強制爲具有特定原型(如'virtual'關鍵字允許我們做的)並且用戶能夠通知構造函數應該使用哪個build()。感謝您的評論。 – gsamaras
你可能尋找一個*概念*,這將有望在今年被指定爲ISO技術規範(但他們不會是C++ 14標準本身的一部分)。 – dyp