[英]Creating an instance of templated abstract class
I would like to instantiate a templated abstract class, like the following one: 我想实例化一个模板化的抽象类,如下所示:
template <class T>
class non_sense {
public:
void virtual nonsesnse_func() = 0;
};
to make an integer instance of this class I tried the following: 为了创建这个类的整数实例,我尝试了以下方法:
void non_sense<int>::nonsesnse_func(){
}
and then I make my instance in main : 然后我在main中创建我的实例:
non_sense<int> xx;
so the whole program is as follow: 所以整个程序如下:
template <class T>
class non_sense {
public:
void virtual nonsesnse_func() = 0;
};
void non_sense<int>::nonsesnse_func(){
}
void main(){
non_sense<int> xx;
}
It totally make sense to me, the compiler doesn't accept it though, saying the class is abstract. 这对我来说完全有意义,编译器不接受它,说这个类是抽象的。 I don't want to take the route of creating a new class inheriting from this class using a specific template, regarding the big application I am trying to make this will be massive writting.
我不想采用创建一个使用特定模板从这个类继承的新类的路线,关于我试图做的大型应用程序,这将是大量的写入。 Can somebody explain to me why the compiler rejects this, and is there any way arround this apart from creating a new class for the specific instance I want.
有人可以向我解释为什么编译器会拒绝这个,除了为我想要的特定实例创建一个新类之外,还有什么方法可以解决这个问题。
non_sense is an abstract class, so it can never be instantiated into an object. non_sense是一个抽象类,因此永远不能将其实例化为对象。
This compiles and runs, however: 然而,这编译并运行:
#include <iostream>
template <class T>
class non_sense {
public:
virtual void nonsesnse_func();
};
// Specialize the method
template<>
void non_sense<int>::nonsesnse_func(){
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
int main(){
non_sense<int> xx;
xx.nonsesnse_func();
return 0;
}
And here's code showing how to make this run with a pure abstract class (I've renamed nosnsnsense to nonsense, it's easier to type ;) : 这里的代码显示了如何使用纯抽象类运行(我将nosnsnsense重命名为废话,更容易键入;):
#include <iostream>
template <class T>
class non_sense {
public:
virtual void nonsense_func() = 0;
};
template<class T>
class non_sense_concrete : public non_sense<T> {
public:
void nonsense_func() {
std::cout << "non_sense_concrete<T> generic code" << std::endl;
}
};
// Specialize the concrete class
template<>
void non_sense_concrete<int>::nonsense_func(){
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
int main(){
non_sense_concrete<double> objectGeneric;
objectGeneric.nonsense_func();
non_sense_concrete<int> objectInt;
objectInt.nonsense_func();
return 0;
}
Odd as it might seem, pure virtual methods can have an implementation in C++. 看起来很奇怪,纯虚方法可以在C ++中实现。 That does not change the fact that the method is pure virtual and the class containing it is abstract.
这并没有改变这个方法是纯虚拟的事实,而包含它的类是抽象的。
If you want the class non_sense
to be abstact for all types except int
, you will have to provide a specialisation for the entire class, not just for the pure virtual members: 如果您希望类
non_sense
对除int
之外的所有类型都是abstact,则必须为整个类提供特化,而不仅仅是纯虚拟成员:
template <class T>
class non_sense {
public:
virtual void nonsense_func() = 0;
};
template <>
class non_sense<int> {
public:
virtual void nonsense_func()
{
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
};
With a larger class, inheritance would probably be easier, because then the derived class can inherit the other members from non_sense
, instead of having to duplicate the entire class (as you need to do when creating a specialisation). 使用更大的类,继承可能会更容易,因为派生类可以从
non_sense
继承其他成员,而不必复制整个类(正如您在创建特化时需要做的那样)。
If you have an class with a pure virtual function (ie abstract) you MUST create a second class that implements that virtual function. 如果你有一个具有纯虚函数(即抽象)的类,你必须创建一个实现该虚函数的第二个类。 Otherwise you will never be able to use that class.
否则你将永远无法使用该类。
In your code you implemented a function alright, but it's not virtual because it is not inside of a class. 在您的代码中,您实现了一个函数,但它不是虚拟的,因为它不在类中。 It needs to be declared and defined as part of a sub-class off of non_sense in order to work.
它需要声明并定义为non_sense子类的一部分才能工作。 Please keep in mind that only classes can have virtual functions.
请记住,只有类可以具有虚拟功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.