我正在使用main.cpp中主要定义的基类和子类 这给了我一个未定义引用的错误: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;
}
答案 0 :(得分:1)
C ++中的接口称为"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 output[T]; // T is read from command line
改为使用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(){}
};