我有一个树类树,我希望能够以不同的方式构建它。 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