我知道你无法模仿虚拟功能,我确实理解它背后的概念。但是我仍然需要一种方法来克服我遇到的一些错误。我可以让我的东西工作,但它看起来不对我。
我有一个名为System
的课程:
#include "Vector.h"
class System
{
virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const = 0;
};
class UnresolvedSystem : public System
{
virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const
{
//do something
}
};
在Vector.h
:
tenplate<typename T>
class Vector
{
//some functions
};
现在我想在VectorToLocal
中对system.h
进行模板化以仅采用Vector<T>
,但我不能这样做,因为它是一个虚函数。我想要一个解决方案。我知道我可以VectorToLocal
将Vector<float>
,Vector<double>
等作为参数,但我不想这样做。
答案 0 :(得分:2)
会员功能模板不能是虚拟的。没有两种方式。
但虚拟成员函数可以采用恰好使用模板的完全定义的类型:
class System
{
public:
virtual void DoIt(vector<int>* v);
};
int main()
{
vector<int> v;
System s;
s.DoIt(&v);
return 0;
}
顺便问一下,为什么要实现自己的矢量类?
答案 1 :(得分:1)
任何消除虚拟功能的常用方法(如CRTP)也会有所帮助。
答案 2 :(得分:0)
我不知道你想用你的向量做什么,但有时候可以让模板函数调用一个实现实际行为的虚函数。在这种情况下,您将在您的超类中实现模板版本,并使其在那里调用非模板纯虚拟,以执行您想要执行的任何操作。这通常只有在对type-parameter:
进行限制时才有效#include "Vector.h"
class System
{
virtual void print( const std::string & ) const = 0;
template<class T>
void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const {
print( T.GetName() );
}
};
class UnresolvedSystem : public System
{
virtual void print( const std::string & Name ) const {
std::cout << name << std::endl;
}
};
在这种情况下,我假设T
有一个成员函数GetName
。
答案 3 :(得分:0)
如果定义C ++模板函数,则会为模板参数类型的每个组合创建一个新的函数实现。因此源中的单个函数可以是机器代码中的一个或多个函数。这有助于使他们快速。
现在,编译器根据调用方式确定要生成函数的哪个版本。如果int
永远不是类型参数,则不会禁止编译器生成实现。现在,如果您进行虚拟调用,则很难找到它的使用方式,并且可能是在编译使用模板函数的函数时函数的定义不在头文件中。如果没有函数的源代码,编译器就无法创建编译函数。
当C ++允许虚拟模板功能时,您还会遇到一些其他不切实际的问题。就像通常实现虚拟功能一样。
这可能是C ++不允许它的原因。您可能认为自己需要它,但可能有另一种方式,我相信如果您向我们提供有关此代码段背后的要求的更多细节,我们相信人们会帮助您找到。
答案 4 :(得分:0)
您有多种选择,全部取决于您要做的事情。
如果T
以某种方式固有System
(例如,如果System
具有T
类型的成员变量),则可以使整个类模板化:< / p>
template< typename T >
class System
{
virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const = 0;
};
template< typename T >
class UnresolvedSystem : public System<T>
{
virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const
{
//do something
}
};
如果T
的上下文仅为VectorToLocal
的本地上下文,那么更好的设计决策是将该函数计算在该类之外:
template< typename T >
void VectorToLocal( System& s, Vector<T>& global_dir, ... )
{
// use s's public interface to make changes to the object
}
您能否提供有关VectorToLocal
的目的的详细信息?
答案 5 :(得分:0)
如果您想要提供单个实施点,则可以将调用转发给模板
struct base {
virtual void f( int );
virtual void f( double );
};
struct derived : base {
virtual void f( int x ) { f_tmpl(x); }
virtual void f( double x ) { f_tmpl(x); }
template <typename T>
void f_tmpl( T x ) { // ... }
};
我敢打赌,使用类型列表可以实际生成虚函数,但这可能会使代码复杂化。