我有一个模板化类的层次结构,它们在一个地方构建并传递到其他地方以对它们进行一些操作。
例如,一个类可以模板化为一些知道如何将自身转换为double的复杂对象,并且模板化类具有将该对象输出为double的操作。效用函数的一个示例是将此类的集合作为表输出的函数。
但是,我不想将此类型作为模板化类传递,因为效用函数应该适用于任何具体的类变体,因为它们都可以表示为double。因此,我想要一些具有'表示为双精度'功能的非模板化接口。为什么以下不起作用?
#include "stdafx.h"
class Interface1
{
public:
virtual int ReturnSomeInt();
};
template<typename myType>
class TClass1 : public Interface1
{
public:
int ReturnSomeInt() {return 5;}
void CalculateSomething(myType myValue) {}
TClass1() {}
};
//---------------------------------------------
class Interface2 : public Interface1
{
public:
virtual double ReturnSomeDouble();
};
template<typename myType>
class TClass2 : public TClass1<myType>, public Interface2
{
public:
double ReturnSomeDouble() {return 9.2;}
void CalculateSomethingElse(myType myValue) {}
TClass2() {}
};
//---------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
Interface2 myInterface = TClass2<float>();
int myInt = myInterface.ReturnSomeInt();
double myDouble = myInterface.ReturnSomeDouble();
return 0;
}
我收到2019年的链接错误,指出它无法找到符号Interface2::ReturnSomeDouble(void)
。可能是什么问题?
答案 0 :(得分:1)
virtual
函数(此处为Interface2::ReturnSomeDouble()
)不能保持未实现。
因为,当对象被实例化时,它需要使用vptr
函数的地址/定义填充隐藏的类成员virtual
,这是找不到的,因此链接器错误。
您必须定义自己的身体或使其成为纯virtual
函数(以便定义成为可选项)。
答案 1 :(得分:0)
这里有slicing。当你复制到变量'myInterface'时,你的TClass2实例已被字面切片(派生类部分已被丢弃)。您需要在堆上实例化TClass2,然后将“myInterface”更改为指针或引用以使其工作。
(作为切片的结果,你的代码正在调用未实现的基类函数。如果你要使基类函数纯虚拟,那么你可能得到了一个更有用的错误信息。)
答案 2 :(得分:0)
1通过声明接口函数使其纯虚拟
virtual double ReturnSomeDouble() const = 0;
以便链接器不会查找基类的相应函数。
2声明interface1
是一个虚拟基础,以避免在Tclass2
中继承它两次,尽管这对你的代码编译并不重要
答案 3 :(得分:0)
由于我的问题有很多好的答案,我决定重新发布我的代码并实施所有有用的评论。
#include "stdafx.h"
class Interface1
{
public:
virtual int ReturnSomeInt()=0;
};
template<typename myType>
class TClass1 : public Interface1
{
public:
int ReturnSomeInt() {return 5;}
void CalculateSomething(myType myValue) {}
TClass1() {}
};
//---------------------------------------------
class Interface2 : public Interface1
{
public:
virtual double ReturnSomeDouble()=0;
};
template<typename myType>
class TClass2 : public TClass1<myType>, public Interface2
{
public:
int ReturnSomeInt() { return TClass1<myType>::ReturnSomeInt(); }
double ReturnSomeDouble() {return 9.2;}
void CalculateSomethingElse(myType myValue) {}
TClass2() {}
};
//---------------------------------------------
void WriteClassToConsole(Interface2& myInterface)
{
std::cout << "My int:\t" << myInterface.ReturnSomeInt() << std::endl;
std::cout << "My dbl:\t" << myInterface.ReturnSomeDouble() << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
TClass2<float> myClass;
WriteClassToConsole(myClass);
std::getchar();
return 0;
}
感谢所有帮助过的人。