繁体   English   中英

模板继承矩阵和平方矩阵C ++

[英]template inheritance matrix and square matrix C++

请帮助我纠正以下错误。

错误1错误C2248:“ SquareMatrix :: SquareMatrix”:无法访问在类“ SquareMatrix”中声明的私有成员

我正在尝试在class(matrix)下实现一个subclass(s​​quare matrix),但我不知道如何解决该错误。 这是代码。

#ifndef _MATRIX_
#define _MATRIX_

#include <iostream>
#include <vector>
using namespace std;

//class matrix starts here

template<class T, int m, int n>
class Matrix{

    vector<vector<T>> elements;
    int nrow;
    int ncol;

public:
    Matrix();
    ~Matrix();

template<class T, int m, int n>
Matrix<T, m, n>::Matrix() : nrow(m), ncol(n){
    for (int i = 0; i < nrow; i++){
        vector<T> row(ncol, 0);
        elements.push_back(row);
    }
}

template<class T, int m, int n>
Matrix<T, m, n>::~Matrix(){}

//here is the inheritance class SquareMatrix

template<class T, int n>
class SquareMatrix : public Matrix<T, n, n>{

    SquareMatrix();
};

template<class T, int n>
SquareMatrix<T, n>::SquareMatrix() :nrow(n), ncol(n){
    for (int i = 0; i < nrow; i++){
        vector<T> row(ncol, 0);
        elements.push_back(row);
    }
}

//Here is the main.cpp

#include "Matrix.h"
using namespace std;

int main(){
    Matrix<double, 3, 2> a;
    SquareMatrix<double, 3> c;
}

通过尝试在派生类构造函数的成员初始化器列表中初始化类的成员变量,您遇到的问题浮出水面。 除非基础是虚拟基础,否则这不是必需的,甚至是不允许的。 相反,只需简单地将can踢到基类,并让其构造函数初始化这些成员:

template<class T, int n>
SquareMatrix<T, n>::SquareMatrix() : Matrix<T,n,n>()
{
}

如果您没有注意到,这也可以修复已发布代码中的另一个逻辑缺陷。 基类已经完成了填充实际elements向量的操作,因此在派生类中也不需要这样做。 调用基类构造为您处理。

改进之处

以下是可以大大简化此代码的工作清单:

  • 矩阵维度模板参数应为无符号数据类型。 矩阵不能有负数,因此代码甚至不允许这样做。
  • 矩阵的行元素也不必要是动态的(向量),而不是固定的(数组)。 让动态内存支持整个结构是有意义的,但是由于模板参数用于声明维,因此您可以将std::array<T,n>用于行类型,并将其包装在动态的std::vector中尺寸m
  • ncolnrow ,因为他们在,基于事实的模板参数的成员不应该对矩阵的一生都在变化。 如果您想保留它们,请将它们更改为public static constexpr (尽管老实说,我认为您没有理由; mn随模板一起出现。
  • 基本类仅是使用相同宽度和高度的约束,它甚至不需要单独的类派生。 您只需using别名即可。

最后,代码简化为:

#include <vector>
#include <array>

// matrix managed on the heap as a vector of arrays
template<class T, size_t m, size_t n>
class Matrix
{
    std::vector<std::array<T, n>> elements;

public:
    static constexpr size_t nrows = m;
    static constexpr size_t ncols = n;

    Matrix() : elements(m)
    {
    }
};

派生的方矩阵类经过简化, using别名可以很简单:

// a square matrix built via a regular matrix
template<class T, size_t m>
using SquareMatrix = Matrix<T,m,m>;

当然,仍然需要以某种方式提供对elements成员的访问,否则,其中大多数都是毫无意义的。

祝您好运,希望对您有所帮助。

SquareMatrix<T, n>::SquareMatrix() :nrow(n), ncol(n){

在这里你的构造函数试图初始化其成员nrowncol

但问题的,当然,是这个类没有任何成员呼吁nrowncol 他们是其超类的私有成员。

模板是一类。 类的构造函数只能初始化其自己的成员。 它不能初始化其超类的任何成员。 超类的构造函数负责初始化其自己的成员。

您没有指定要使用的编译器,但这是一个非常糟糕的错误消息。 gcc的错误消息更有意义:

t.C:40:37: error: class ‘SquareMatrix<T, n>’ does not have any field named ‘nrow’
 SquareMatrix<T, n>::SquareMatrix() :nrow(n), ncol(n){

PS帮个忙,完全忘了“使用命名空间std”; 只是假装C ++中没有这样的东西。 特别是在头文件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM