c++模板抽象继承
c++ template abstract inheritance
我是计算机图形学硕士学位最后一年的学生,我们必须用C++做一个练习。
这是代码:
AbsMatrice.h
:
#pragma once
template<int M,int N, typename T>
class AbsMatrice
{
private:
T m_data[M][N];
public:
AbsMatrice();
~AbsMatrice();
AbsMatrice<M, N, T> mul(AbsMatrice<M,N,T> &a);
AbsMatrice<M, N, T> add(AbsMatrice<M, N, T> &a);
void read(...);
T& at(int row, int col);
T& operator ()(int row, int col);
//fonction virtuelle pure
virtual void print() = 0;
int& getNumRows(){ return M; }
int& getNumColumns(){ return N; }
};
Matrice.h
:
#pragma once
#include "AbsMatrice.h"
template <int M, int N, typename T>
class Matrice : public AbsMatrice<M,N,T>
{
public:
Matrice();
~Matrice();
void print();
};
AbsMatrice.cpp
:
#include "AbsMatrice.h"
#include <iostream>
template<int M, int N, typename T>
AbsMatrice<M, N, T>::AbsMatrice(){
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
m_data[i][j] = 0;
}
}
}
template<int M, int N, typename T>
AbsMatrice<M, N, T>::~AbsMatrice()
{
}
template<int M, int N, typename T>
T& AbsMatrice<M, N, T>::operator ()(int row, int col)
{
return m_data[row][col];
}
template<int M, int N, typename T>
T& AbsMatrice<M, N, T>::at(int row, int col)
{
return m_data[row][col];
}
template<int M, int N, typename T>
AbsMatrice<M, N, T> AbsMatrice<M, N, T>::add(AbsMatrice<M, N, T> &a)
{
if (this->getNumColumns() == a.getNumColumns() && this->getNumRows() == a.getNumRows())
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
m_data[i][j] += a(i, j);
}
}
}
else
std::cout << "Erreur matrice de taille différentes !" << std::endl;
return this;
}
template<int M, int N, typename T>
void AbsMatrice<M, N, T>::print()
{
std::cout << "la matrice :" << std::endl;
}
Matrice.cpp
:
#include "Matrice.h"
#include <iostream>
template <int M, int N, typename T>
Matrice<M,N,T>::~Matrice()
{
}
template <int M, int N, typename T>
void Matrice<M, N, T>::print()
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
std::cout << " " << this->m_data[i][j] << " ";
}
std::endl;
}
}
当我主要尝试这样做时:
main.cpp:
#include "Matrice.h"
int main()
{
Matrice<2,2,int> a;
Matrice<2,2,int> b;
}
我得到了一个讨厌的:
error C2259: 'AbsMatrice<2,2,T>' : cannot instantiate abstract class
1> with
1> [
1> T=int
1> ]
1> due to following members:
1> 'void AbsMatrice<2,2,T>::print(void)' : is abstract
1> with
1> [
1> T=int
1> ]
1> c:usersbobmazadocumentsvisual studio 2013projectstpmatricestpmatricesabsmatrice.h(22) : see declaration of 'AbsMatrice<2,2,T>::print'
1> with
1> [
1> T=int
1> ]
我试着在网上到处搜索,但没有找到与我相似的案例,大多数人也没有使用相同的签名来覆盖抽象函数,但我的情况并非如此。我从来没有见过这样的错误,提前谢谢你。
错误消息的含义是什么?如何更正?
注意:我已经用c++编程好几年了,但从来没有做过这样的事情,所以我想不通!
附言:对不起,我是在法国的学生。
编辑:感谢大家的帮助,我第一次不得不在这里请求阿伦,伟大的社区!
您需要定义您的函数,而不仅仅是声明它:
virtual void print() {}
编译器告诉发生了什么-void Matrice<M,N,T>::print()
没有声明为virtual
,因此导致纯虚拟函数virtual void print() = 0
不会过载。
为了避免将来出现这种情况,请将重载(虚拟)函数指定为override
。
此外,我假设print
函数不修改对象的内部状态,并一直工作,因此const noexcept
说明符是合适的。
以下是一个片段,它可能会帮助您实现更安全的虚拟函数重载
class Interface
{
public:
virtual ~Interface() {}
virtual void print() const noexcept = 0;
};
class Implementation : public Interface
{
public:
virtual ~Implementation() {}
virtual void print() const noexcept override
{
...
}
};
- 当在重载函数中声明更宽松的
throw specifier
时错误被激发 - 当声明较宽松的
internal state specifier
时在重载函数中,会触发错误 - 当
overriding
函数不覆盖,则会触发错误
模板必须始终完全定义,因为无论何时实例化模板,编译器都会生成一个实现,并指定具体的模板参数。因此,无论在哪里使用模板,所有方法体都必须可用。这就是为什么模板类/库通常包含在单个.hpp
文件中。
这对你的案子意味着什么?即使在某些.cpp
文件中有Matrice<int,int,typename>::print()
的模板实现,编译器在编译main.cpp
时也看不到它。因此,它无法生成Matrice<2,2,int>::print()
的实现,因此,没有该方法的定义。它看到的只是virtual AbsMatrice::print() = 0;
首先,由于AbsMatrice
是纯虚拟的,因此不能按值返回抽象类型,因此必须返回引用或指针:
AbsMatrice<M, N, T>& mul(AbsMatrice<M, N, T> &a);
^
AbsMatrice<M, N, T>& add(AbsMatrice<M, N, T> &a);
^
其次,基类的析构函数必须声明为virtual
,以避免潜在的内存泄漏。
virtual ~AbsMatrice();
- 从抽象类继承以创建另一个抽象类时,我应该重新声明所有虚函数吗?
- 抽象类析构函数与继承"Shutdown"函数
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- C++的抽象类继承和构造函数的问题
- 自定义异常中的用户定义的空构造函数,具有多个继承和抽象基类
- C++:抽象类继承和构造
- 使用空基类强制继承抽象工厂的做法是不好的吗?
- 私下继承C++抽象基类是什么意思
- 抽象类 A 由类 C 继承"through"类 B "intermediary"。如何声明虚拟功能?
- 如何修复抽象类的迭代继承
- 具有继承类和函数的抽象类写入单独的向量c++
- 继承自C++中的抽象类
- C++抽象类和继承
- 继承抽象的基础接口及其实现给出了C2259
- 如何从 c++ 基类继承抽象行为
- 如何使用继承(抽象基类)实现移动构造函数和移动赋值运算符
- 多重继承抽象类
- C++ 继承抽象函数
- c++元编程:必须继承抽象类的模板参数