好的,首先是示例代码;这是我试图传达我正在尝试做的事情,尽管它没有编译:
#include <iostream>
template <class T>
class Base
{
public:
virtual void my_callback() = 0;
};
class Derived1
: public Base<int>
, public Base<float>
{
public:
void my_callback<int>()
{
cout << "Int callback for Derived1.\n";
}
void my_callback<float>()
{
cout << "Float callback for Derived\n";
}
};
class Derived2
: public Base<int>
, public Base<float>
{
public:
void my_callback<int>()
{
cout << "Int callback for Derived2.\n";
}
void my_callback<float>()
{
cout << "Float callback for Derived2\n";
}
};
int main()
{
{
Derived1 d;
Base<int> * i_p = d;
Base<float> * i_f = d;
i_p->my_callback();
i_f->my_callback();
}
{
Derived2 d;
Base<int> * i_p = d;
Base<float> * i_f = d;
i_p->my_callback();
i_f->my_callback();
}
//Desired output:
// Int callback for Derived1.
// Float callback for Derived1
// Int callback for Derived2.
// Float callback for Derived2
system("Pause");
}
所以,我正在尝试做的是创建一种包装类来继承,它将自动将派生类连接到各种回调列表;它需要将派生类的特定实例连接到列表,并且我希望“user”具有/ get来使回调函数作为创建派生类的一部分,如您所见。
看起来这应该可以工作,虽然我可能需要使用不同的语法。如果它不起作用,你有什么建议吗?
答案 0 :(得分:2)
你想要的是不可能。
您可以添加模板专精,但我不知道这是否真的有用:
template <class T>
class Base {
public:
virtual void my_callback() = 0;
};
template <>
class Base<int> {
public:
virtual void my_callback() {
cout << "Base<int>::my_callback()\n";
}
};
template <>
class Base<float> {
public:
virtual void my_callback() {
cout << "Base<float>::my_callback()\n";
}
};
class Derived1 : public Base<int>, public Base<float> {
public:
// NOTE: no my_callback() implementation here
};
class Derived2 : public Base<int>, public Base<float> {
public:
virtual void my_callback() {
cout << "Derived2::my_callback()\n";
}
};
int main()
{
{
Derived1 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;
i_p->my_callback();
i_f->my_callback();
}
{
Derived2 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;
i_p->my_callback();
i_f->my_callback();
}
}
输出:
Base<int>::my_callback()
Base<float>::my_callback()
Derived2::my_callback()
Derived2::my_callback()
让我试着解释一下原因:
Derived1 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;
// will check the vtable, and will call
// either Derived1::my_callback
// OR Base<int>::my_callback
i_p->my_callback();
// will check the vtable, and will call
// either Derived1::my_callback
// OR Base<float>::my_callback
i_f->my_callback();
虽然通过vtable在Derived1类中有两个版本的my_callback(),你不能覆盖它们中的任何一个,你只能一次覆盖它们(就像Derived2在示例中那样)!
你应该只提供两个方法“my_callback1()”和“my_callback2()”。
答案 1 :(得分:1)
是的,你可以做到这一点:
#include <iostream>
using namespace std;
template <class T>
class Base
{
public:
virtual void my_callback() = 0;
};
class Derived1 : public Base<int>, public Base<float>
{
public:
void Base<int>::my_callback() {
cout << "Int callback for Derived1.\n";
}
void Base<float>::my_callback() {
cout << "Float callback for Derived\n";
}
};
class Derived2 : public Base<int>, public Base<float>
{
public:
void Base<int>::my_callback() {
cout << "Int callback for Derived2.\n";
}
void Base<float>::my_callback() {
cout << "Float callback for Derived2\n";
}
};
int main()
{
{
Derived1 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;
i_p->my_callback();
i_f->my_callback();
}
{
Derived2 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;
i_p->my_callback();
i_f->my_callback();
}
}
输出:
Int callback for Derived1.
Float callback for Derived
Int callback for Derived2.
Float callback for Derived2
答案 2 :(得分:0)
无论是使用模板类还是非模板类,都可以使用this style或this one中的辅助类来完成。
(如果您不打算使用Microsoft特定的限定名称,这似乎是唯一的便携式解决方案。)
答案 3 :(得分:-1)
与模板相关联的虚拟不会引发警报吗? ;)
您必须选择静态或动态的一面。