我在 main.cpp 的 main 上面定义了一个基类和一个子类 这给了我一个 undefined reference 的错误 FactoryTraversal::AddPoint::AddPoint(int const&, int const&, int)' 这是代码:
#include <iostream>
#include <list>
#include <typeinfo>
#include <cmath>
enum traversal_type
{
TRAVERSAL = 0,
TRAVERSALMAX
};
template <class T>
class FactoryTraversal
{
public:
FactoryTraversal();
FactoryTraversal *CreateInstance(const traversal_type &type);
virtual ~FactoryTraversal();
const std::list<int>& GetIndices() const {return indices;}
int GetIndicesSize() const {return indices.size();}
virtual void AddPoint(const T &x, const T &y, int index);
protected:
std::list<int> indices;
};
template<class T>
class Traversal : public FactoryTraversal<T>
{
public:
Traversal();
void AddPoint(const T &x, const T &y, int index);
int GetResultXOR() const {return result_xor;}
private:
T coords_s[2];
T coords_e[2];
int result_xor;
void update_result(int index);
T calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2);
};
template<class T>
Traversal<T>::Traversal():FactoryTraversal<T>()
{
//Do nothing
}
template<class T>
void Traversal<T>::AddPoint(const T &x, const T &y, int index)
{
if (0 == this->GetIndicesSize())
{
this->indices.push_front(index);
coords_s[0] = x; coords_s[1] = y;
coords_e[0] = x; coords_e[1] = y;
}
else
{
T d1 = this->calculate_distance(x,coords_s[0],y,coords_s[1]);
T d2 = this->calculate_distance(x,coords_e[0],y,coords_e[1]);
if (d1 < d2)
{
this->indices.push_front(index);
coords_s[0] = x; coords_s[1] = y;
}
else
{
this->indices.push_back(index);
coords_e[0] = x; coords_e[1] = y;
}
}
this->update_result(index);
}
template<class T>
T Traversal<T>::calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2)
{
if (typeid(T) == typeid(int))
{
return std::min(std::abs(x1-x2),std::abs(y1-y2));
}
return 0;
}
template<class T>
void Traversal<T>::update_result(int index)
{
if (0 == this->GetIndicesSize())
result_xor = index;
else
result_xor ^= index;
}
template<class T>
FactoryTraversal<T>::FactoryTraversal()
{
indices.clear();
}
template<class T>
FactoryTraversal<T>::~FactoryTraversal()
{
//Do Nothing
}
template<class T>
FactoryTraversal<T>* FactoryTraversal<T>::CreateInstance(const traversal_type &type)
{
if (TRAVERSAL == type)
return new Traversal<T>();
else
return NULL;
}
FactoryTraversal<int> factory_traversal;
Traversal<int> *traversal = new Traversal<int>();
int main()
{
int T;
std::cin>>T;
int output[T];
for (int i = 0; i < T; ++i)
{
int N;
std::cin>>N;
FactoryTraversal<int> factory_traversal;
FactoryTraversal<int> *traversal = factory_traversal.CreateInstance(TRAVERSAL);
for (int j = 0; j < N; ++j)
{
int x, y;
std::cin>>x>>y;
traversal->AddPoint(x,y,j+1);
}
Traversal<int> *tmp = dynamic_cast<Traversal<int> *>(traversal);
if (tmp)
output[i] = tmp->GetResultXOR();
else
output[i] = 0;
}
for (int i = 0; i < T; ++i)
{
std::cout<<output[i]<<std::endl;
}
return 0;
}
最佳答案
C++ 中的接口(interface)称为 "abstract classes" ,如果类至少有一个“纯虚函数”,则它们是抽象的。如果一个函数以 virtual
为前缀并且在其声明中有一个尾随 =0
,则该函数是一个纯虚函数。这就是您想要的 FactoryTraversal::AddPoint
:
virtual void AddPoint(const T &x, const T &y, int index) = 0;
现在派生类应该定义它(确实如此)。如果 AddPoint
不是纯虚拟的,您将被迫在基类中为它提供一个实现,您可以简单地这样做:
virtual void AddPoint(const T &x, const T &y, int index){}
当派生类选择不重写该方法时,这会提供一个“默认”或回退实现。如果它是纯虚拟的,则派生类强制定义它,以免调用它导致编译器错误(否则派生类也被认为是抽象的)。
请注意,析构函数永远不应该是纯虚拟的。你现在拥有它的方式很棒;你不知不觉地遵守了我在上面概述的规则。
一些其他注意事项:
可变长度数组不是合法的 C++,这是一个编译器扩展:
int 输出[T];//T 从命令行读取
使用 vector
相反:
std::vector<int> output(T);
您原样存在内存泄漏。使用像
unique_ptr
这样的托管指针所以你不必担心new
和delete
我说过您希望
AddPoint
是纯虚拟的,我是认真的。但是,如果这是您采取的第一步,您的代码将无法编译。看起来您将基类和工厂合并为一个;把它们分开。
将它们放在一起,我们可以将新的基类定义为:
template<class T>
class TraversalBase
{
public:
virtual ~TraversalBase(){}
const std::list<int>& GetIndices() const {return indices;}
int GetIndicesSize() const {return indices.size();}
virtual void AddPoint(const T &x, const T &y, int index) = 0;
protected:
std::list<int> indices;
};
派生类变为(变化很小,还要注意 override
关键字):
template<class T>
class Traversal : public TraversalBase<T>
{
public:
void AddPoint(const T &x, const T &y, int index) override;
int GetResultXOR() const {return result_xor;}
private:
T coords_s[2];
T coords_e[2];
int result_xor;
void update_result(int index);
T calculate_distance(const T &x1, const T &x2, const T &y1, const T &y2);
};
我们的 Factory 类被大大简化了:
template <class T>
struct FactoryTraversal
{
FactoryTraversal(){}
std::unique_ptr<TraversalBase<T>> CreateInstance(const traversal_type &type);
~FactoryTraversal(){}
};
Live Demo (C++11)
关于c++ - 在 main 函数调用期间使用 main 上面的模板类给出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44070653/