【发布时间】:2014-06-13 13:47:50
【问题描述】:
下面的代码没有产生我想要的。
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
template<typename T> class Parent;
template<typename T> class Child1;
template<typename T> class Child2;
template<typename T> T fcn_default(const Parent<T> &obj, const T &phit){
return 3.2 + phit;
}
template<typename T> T fcn_mod1 (const Child1<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Child2<T> &obj, const T &phit){
return 2.2 + phit;
}
template<typename T> class Parent{
public:
Parent() {
fcn_ptr = &fcn_default;
}
T do_something(const T &phit){
return this->fcn_ptr(*this, phit);
}
T (*fcn_ptr)(const Parent &, const T &);
};
template<typename T> class Child1 : public Parent<T>{
public:
Child1() {
}
T (*fcn_ptr)(const Child1 &, const T &);
};
template<typename T> class Child2 : public Parent<T>{
public:
Child2() {
}
T (*fcn_ptr)(const Child2 &, const T &);
};
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
test12->fcn_ptr = &fcn_mod1;
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
test2->fcn_ptr = &fcn_mod2;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
cout << "test" << endl;
}
它产生:
5.2
5.2
5.2
test
我期待:
5.2
3.2
4.2
test
我的理解是向量 objects 属于 Parent 类型,因此调用它自己的方法而不是孩子的方法。
我几乎用“奇怪的重复模板模式”破解了它,但在向量对象的初始化过程中我遇到了最后一个问题。
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
template<class Child, typename T> class Parent;
template<typename T> class Child1;
template<typename T> class Child2;
template<typename T> T fcn_mod1 (const Child1<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Child2<T> &obj, const T &phit){
return 2.2 + phit;
}
template<class Child, typename T> class Parent{
public:
Parent() {
fcn_ptr = &Parent::fcn_default;
}
T do_something(const T &phit){
return static_cast<Child*>(this)->fcn_ptr(static_cast<Child*>(this), phit);
}
T (*fcn_ptr)(const Child &, const T &);
private:
static T fcn_default(const Child &obj, const T &phit){
return 3.2 + phit;
}
};
template<typename T> class Child1 : public Parent<Child1<T>,T>{
public:
Child1() {
}
T (*fcn_ptr)(const Child1 &, const T &);
};
template<typename T> class Child2 : public Parent<Child2<T>,T>{
public:
Child2() {
}
T (*fcn_ptr)(const Child2 &, const T &);
};
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
test12->fcn_ptr = &fcn_mod1;
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
test2->fcn_ptr = &fcn_mod2;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
cout << "test" << endl;
}
** +++++ 更新 +++++ **
如果我将成员添加到子类,例如,我无法从 fcn_mod2 中访问它。也许虚函数可以提供帮助?
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
template<typename T> class Parent;
template<typename T> class Child1;
template<typename T> class Child2;
template<typename T> T fcn_default(const Parent<T> &obj, const T &phit){
return 3.2 + phit;
}
template<typename T> T fcn_mod1 (const Parent<T> &obj, const T &phit){
return 1.2 + phit;
}
template<typename T> T fcn_mod2 (const Parent<T> &obj, const T &phit){
return 2.2 + phit + param2*0.001;
}
template<typename T> class Parent{
public:
Parent() {
fcn_ptr = &fcn_default;
}
T do_something(const T &phit){
return this->fcn_ptr(*this, phit);
}
T (*fcn_ptr)(const Parent &, const T &);
};
template<typename T> class Child1 : public Parent<T>{
public:
Child1() {
}
};
template<typename T> class Child2 : public Parent<T>{
public:
Child2() {
}
T param2;
};
typedef double lrtType;
int main(){
std::vector< Parent<lrtType> * > objects;
Child1<lrtType> *test11 = new Child1<lrtType>();
objects.push_back(test11);
Child1<lrtType> *test12 = new Child1<lrtType>();
test12->fcn_ptr = &fcn_mod1;
objects.push_back(test12);
Child2<lrtType> *test2 = new Child2<lrtType>();
test2->fcn_ptr = &fcn_mod2;
test2->param2 = 4;
objects.push_back(test2);
for (size_t i = 0; i < objects.size(); ++i) {
std::cout << objects[i]->do_something(2) << std::endl;
}
cout << "test" << endl;
}
【问题讨论】:
-
那么,问题是什么?
-
这看起来不必要的复杂,代码应该解决问题,而不是创建问题
-
我知道你是still at it,但现在已经提高了赌注。既然您已经有了继承层次结构,为什么不为此使用
virtual函数呢? -
@Praetorian:确实,但问题不同,因此是新帖子。我应该虚拟化哪一个?
-
@Rufus 在
Parent中添加一个virtual成员函数,它执行fcn_default()正在执行的操作。Childx类可以在其实现中覆盖该函数。此外,如果您计划通过Parent *处理deleteingChildx对象,您的Parent类需要virtual析构函数。