“继承"纯虚函数的实现 [英] "Inherit" the implementation of a pure virtual function

查看:87
本文介绍了“继承"纯虚函数的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要的东西:

我希望所有子类都能够将其名称作为字符串返回(使用通用函数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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆