[英]Issues with C++ template arguments for inheritance
我对C ++模板有疑问。 更具体地说,通过使用模板参数进行继承。 在开放源代码的第三方库中,我面临着奇怪的行为。 有C方法
factoryReg(const char*, ICallback*)
它允许注册ICallback的子类并覆盖(简化的)方法:
class ICallback
{
public:
virtual void ENTRY(void* data) = 0;
virtual void EXIT(void* data) = 0;
const char* getName() { return _name; } const
ICallback(const char* name) : _name(name) {}
virtual ~ICallback() {}
private:
const char* _name;
};
我有
class BaseCallback : public ICallback
{
public:
BaseCallback(const char* name) : ICallback(name) {}
virtual void ENTRY(void* data) {
std::cout << "in ENTRY base" << std::endl;
}
virtual void EXIT(void* data) {
std::cout << "in EXIT base" << std::endl;
};
class SpecialCallback : public BaseCallback
{
public:
SpecialCallback(const char* name) : BaseCallback(name) {}
virtual void ENTRY(void* data) {
// actually, it's 3rd party code too - assumed to do something like
...
BaseCallback::ENTRY();
}
// no redecl. of EXIT(void* data)
};
template <typename Base>
TemplCallback : public Base
{
public:
TemplCallback(Base& myT) : Base(myT.getName()), _myT(myT)
virtual void ENTRY(void* data) {
std::cout << "in ENTRY templ." << std::endl;
_myT.ENTRY();
}
virtual void EXIT(void* data) {
std::cout << "in EXIT templ." << std::endl;
_myT.EXIT();
}
private:
Base& _myT;
}
注册后
SpecialCallback spc("validName");
TemplCallback<SpecialCallback> myCallback(spc);
factoryReg(spc.getName(), &myCallback);
...
// output: "in ENTRY base"
// "in EXIT base"
回调以某种方式不起作用(调试输出未输出//断点不适用)。
如果我在模板类TemplCallback中省略了EXIT(void * data)方法的实现,则一切正常!
// output: "in ENTRY templ."
// "in EXIT base"
这是预期的行为吗? 我被告知这可能是我使用的MSVC编译器13.10.6030的问题。 不确定。
顺便说一句:这里提出的模板想法可能不是我尝试做的任何事情的最佳选择;)但是,无论设计问题如何,我仍然对这件事本身感兴趣。
我怀疑factoryReg
实际上并没有调用回调,而是存储了指针并在发生某些情况时调用了回调。
如果是这种情况,则此代码:
TemplCallback<SpecialCallback> myCallback(spc);
factoryReg(spc.getName(), &myCallback);
使factoryReg
存储指向一个临时指针,该指针将在您的注册函数返回后立即超出范围。 因此,在调用回调时,该对象不是活动的,并且您具有未定义的行为。
您的TemplCallback
类看起来很有趣。 我认为您实际上并不希望它使用其他对象,而是调用ENTRY
和EXIT
的继承版本:
template <class Base>
class TemplCallback : public Base
{
public:
TempCallback(const char* name) : Base(name)
{}
virtual ENTRY(void* data)
{
// do special processing
Base::ENTRY(data);
}
virtual EXIT(void* data)
{
// do special processing
Base::EXIT(data);
}
};
好的,可以肯定地假设SpecialCallback :: ENTRY()以某种方式调用BaseCallback :: EXIT()。 不能100%确定,因为它是封闭源代码-但很有可能。
“回调”功能就这么多...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.