“继承"纯虚函数的实现 [英] "Inherit" the implementation of a pure virtual function
问题描述
我想要的东西:
我希望所有子类都能够将其名称作为字符串返回(使用通用函数GetName()).
必须通过基类指针访问GetName函数,并返回特定子类的名称.
我的想法:
1. 我使用带有纯虚函数GetName()的抽象基类来强制所有子类都实现此功能.
What I want:
I want that all of my child classes are able to return their name as string (using a common function GetName()).
The GetName function has to be accessible through the base class pointer, returning the name of the specific child class.
My idea:
1. I use an abstract baseclass with a pure virtual function GetName() to force all child classes to implement this function.
class Base
{
const char* GetName() const =0;
}
2. 为了防止实际上必须为所有子类实现此功能,我使用了反复出现的模板模式来继承"每个子类的GetName函数的实现. :
2. To prevent to actually having to implement this function for all child classes I use the curiously recurring template pattern to "inherit" the implementation of the GetName function for each child class:
template<typename SpecificClass>
class ClassNameInfo
{
const char* GetName() const
{
return typeid(SpecificClass).name();
}
}
3. 子类继承自Base(可通过公共基类指针访问),并继承自ClassNameInfo来继承"该特定类的GetName()实现. :
3. The child classes inherit from Base (to be accessible through a common base class pointer) and from ClassNameInfo to "inherit" an implementation of GetName() for this specific class:
class ChildA : public Base, public ClassNameInfo<ChildA>
{
//...
}
class ChildB : public Base, public ClassNameInfo<ChildB>
{
//...
}
问题:
继承纯虚拟功能的实现似乎无效.有任何想法吗?
Problem:
Inheriting an implementation for a pure virtual function does not seem to work. Any ideas?
推荐答案
只需在基类中放置一个公共方法即可,该方法返回由this
指针表示的对象的名称.它甚至不必是纯虚拟的.
Just put a public method in the base class that returns the name of the object represented by the this
pointer. It doesn''t even have to be pure virtual.
当一个类没有任何虚函数时,Typeinfo被静态绑定-编译器确定在编译时使用哪种typeinfo .如果您有一个虚函数,则在运行时从v_table中查找type_info.如果您按照第三个答案或CPalini在第二个答案中所做的方式来定义基数,则最终不会得到正确的类的type_info.结合一个虚拟功能,一切都会好起来的.
为了说明这一点:
Typeinfo is bound statically when a class doesn''t have any virtual functions - the compiler works out which typeinfo to use at compile time. If you have one virtual function then the type_info is looked up at runtime from the v_table. If you define base the way you do in the third answer or CPalini did in the second you''ll not end up with the correct type_info for a class. Bung on one virtual function and all will be well.
To illustrate this:
#include <typeinfo>
#include <string>
template<typename T>
std::string type_name_string( const T *p )
{
return typeid( *p ).name();
}
class A
{
};
class B: public A
{
};
int main()
try
{
B b;
std::cout << type_name_string( static_cast<const A *>( &b ) ) << std::endl;
}
catch( std::exception &e )
{
std::cout << "Something went wrong: " << e.what() << std::endl;
}
catch( ... )
{
std::cout << "Something went wrong, no idea what!" << std::endl;
}
在VC ++ 2010上,这始终会打印"A类".
现在将虚拟函数添加到A ...
On VC++ 2010 this always prints "class A."
Now add a virtual function to A...
#include <typeinfo>
#include <string>
template<typename T>
std::string type_name_string( const T *p )
{
return typeid( *p ).name();
}
class A
{
public:
virtual ~A(){}
};
class B: public A
{
};
int main()
try
{
B b;
std::cout << type_name_string( static_cast<const A *>( &b ) ) << std::endl;
}
catch( std::exception &e )
{
std::cout << "Something went wrong: " << e.what() << std::endl;
}
catch( ... )
{
std::cout << "Something went wrong, no idea what!" << std::endl;
}
现在总是打印"B类".
就我个人而言,我不会费心将类型自省作为类的成员-关于使类成员成为唯一成员的事情是确保您在基类中具有虚函数,而这可能是您想要的,也可能不是.并不是所有的类都需要虚函数,所以我有点讨厌将它们粘在不需要的地方.
干杯,
灰
PS:购买Stroustrup的"C ++编程语言"的副本.他介绍了如何使用typeid和type_info,包括至少一个虚函数的要求.有关更多为什么它会在C ++中如此工作"的信息,由同一位作者撰写,对"C ++的设计和演进"一文.
Which now always prints "class B."
Personally I''d not bother making type introspection a member of a class - about the only thing making it a class member does is guarentee that you have a virtual function in the base class, which may or may not be what you want. Not all classes need virtual functions so I''d be a bit loathe to stick them in where they''re not needed.
Cheers,
Ash
PS: Buy a copy of the "C++ Programming Language" by Stroustrup. He goes over how to use typeid and type_info including the requirement for at least one virtual function. For more "why it works that way in C++" have a gawp at "The Design and Evolution of C++" by the same author.
怎么了?
What''s wrong with
class Base
{
public:
const char* GetName() const
{
return typeid(*this).name();
}
};
?
?
这篇关于“继承"纯虚函数的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!