简体   繁体   English

解引用指向类内部对象的指针

[英]Dereferencing a pointer to an object inside its class

I have SquareMatrix defined as such 我有SquareMatrix定义SquareMatrix

SquareMatrix.h 方阵

#ifndef SQUAREMATRIX_H
#define SQUAREMATRIX_H
#include "Matrix.h"
#include <vector>

class SquareMatrix : public Matrix
{
    public:
        SquareMatrix();
        SquareMatrix(std::vector<std::vector<long double> >);
        //~SquareMatrix();    //just in case there is dynamic memory explicitly used
        //convenient member functions exclusive to SquareMatrix
        bool isUpperDiagonalMatrix() const;
        static SquareMatrix identityMatrix(unsigned);
        void LUDecompose();
        SquareMatrix *Lptr, *Uptr, *Pptr; //should be initialized by LUDecompose before using
    protected:
        void validateData();
    private:

};

#endif // SQUAREMATRIX_H

and I am trying to set Lptr , Uptr (and maybe Pptr ) with a call to SquareMatrix::LUDecompose() . 我试图通过调用SquareMatrix::LUDecompose()来设置LptrUptr (也许还有Pptr SquareMatrix::LUDecompose() It is defined below: 定义如下:

void SquareMatrix::LUDecompose()
{
    unsigned rowCount = this->getRowCount();
    //initialize L to identityMatrix
    *this->Lptr = SquareMatrix::identityMatrix(rowCount);
    //initialize U to sparse matrix with the first row containing the sole non-zero elements
    std::vector<std::vector<long double> > UData(1, this->matrixData[0]);   //making first rowVector the first rowVector of this
    UData.insert(UData.end(), rowCount - 1, std::vector<long double>(rowCount,0)); //making all other rowVectors zero vectors
    *Uptr = SquareMatrix(UData);
    // attempting to perform LU decomposition
    for (unsigned j = 0; j < rowCount; j++)
    {
        long double pivot = Uptr->matrixData[j][j];
        //the pivot should be non-zero; throwing exception that should effectively cause function to return
        if (pivot == 0)
            throw MatrixArithmeticException(LU_DECOMPOSITION_FAILURE);
        for (unsigned k = j+1; k < rowCount; k++)
        {
            if (j == 0)
            {
                //using *this to compute entries for L,U
                this->Lptr->matrixData[k][j] = (this->matrixData[k][j])/pivot;   //setting columns of L
                long double multiplier = this->Lptr->matrixData[k][j];
                //setting row of U
                for (unsigned l = k; l < rowCount; l++)
                {
                    Uptr->matrixData[k][l] = (this->matrixData[k][l])-multiplier*(this->matrixData[0][l]);
                }
            }
            else
            {
                //using U to compute entries for L,U
                //same procedure as before
                this->Lptr->matrixData[k][j] = (Uptr->matrixData[k][j])/pivot;
                long double multiplier = this->Lptr->matrixData[k][j];
                for (unsigned l = k; l < rowCount; l++)
                {
                    Uptr->matrixData[k][l] -= multiplier*(Uptr->matrixData[0][l]);
                }
            }
        }
    }
}

Upon trying to test out this function, it throws a segmentation fault at me, with the last line being the first line where I attempt to manipulate Lptr . 在尝试测试此功能时,它向我抛出了分段错误,最后一行是我尝试操纵Lptr的第一行。

I attempt to change the object pointed by Lptr , and I know that I will not be able to reference the function and set the pointer equal to that reference. 我尝试更改Lptr指向的对象 ,并且我知道我将无法引用该函数并将指针设置为与该引用相等。 In other words, my compiler (GNU GCC compiler) will not allow this->Lptr = &SquareMatrix::identityMatrix(rowCount); 换句话说,我的编译器(GNU GCC编译器)不允许this->Lptr = &SquareMatrix::identityMatrix(rowCount); as it will throw an -fpermissive type error. 因为它将引发-fpermissive类型错误。

Note: SquareMatrix::identityMatrix(unsigned) is defined as: 注意: SquareMatrix::identityMatrix(unsigned)定义为:

SquareMatrix SquareMatrix::identityMatrix(unsigned size)
{
    std::vector<long double> rowVector(size, 0L);
    std::vector<std::vector<long double> > identityMatrixData;
    for (int i = 0; i < size; i++)
    {
        //setting the rowVector to zero-one vector
        rowVector[i] = 1L;
        if (i > 0) rowVector[i-1] = 0L;
        //pushing rowVector into identityMatrixData
        identityMatrixData.push_back(rowVector);
    }
    return SquareMatrix(identityMatrixData);
}

What do you think you CAN do about it? 您认为您可以做什么?

I think I have two options: 我认为我有两种选择:

  1. throw the object on the heap, and then try to set it with the function (that would seem useless as you are redefining the object you just defined by throwing it on the heap) 将对象扔到堆上,然后尝试使用函数进行设置(当您通过将对象扔到堆上重新定义刚刚定义的对象时,这似乎毫无用处)
  2. get c++11 (or something similar) 得到c ++ 11(或类似的东西)
  3. Make the function a helper function that returns a std::vector<SquareMatrix*> of size two (containing pointers to the two desired SquareMatrix values), and create a function that calls the helper function and sets Lptr , Uptr to the respective elements of the returned vector . 使函数返回一个辅助函数std::vector<SquareMatrix*>大小的2(含有指针指向两个期望的SquareMatrix值),并创建调用辅助函数和设定功能LptrUptr到的各个元件返回的vector

Are my options this limited?? 我的选择受限吗?

*Uptr = SquareMatrix(UData); in LUDecompose() is the problem. LUDecompose()就是问题所在。 You cannot set the pointer to an object that is being destroyed when the function returns. 您不能将指针设置为函数返回时将被破坏的对象。 Then the pointer is a dangling pointer and whenever you attempt to use it, it'll segfault. 然后,该指针是一个悬空指针,每当您尝试使用它时,它都会出现段错误。

You need to do Uptr = new SquareMatrix(UData); 您需要做Uptr = new SquareMatrix(UData); . Then in your destructor, call delete Uptr; 然后在析构函数中,调用delete Uptr; .

If you have access to C++11, you can use std::unique_ptr or any pointer containers/wrappers. 如果可以访问C ++ 11,则可以使用std::unique_ptr或任何指针容器/包装器。

Examples of your options: 选项示例:

#include <memory>

class Matrix
{
    public:
        Matrix() {}
        virtual ~Matrix() {}
};

class SqMatrix : public Matrix  //using raw pointers. You must remember to delete your pointers.
{
    private:
        SqMatrix* UPtr = nullptr;

    public:
        SqMatrix() : Matrix() {}
        void InitPtrs() {delete UPtr; UPtr = new SqMatrix();}
        ~SqMatrix() {delete UPtr;}
};

class OMatrix : public Matrix //No need to worry about clean up.
{
    private:
        std::unique_ptr<OMatrix> OPtr;

    public:
        OMatrix() : Matrix() {}
        void InitPtrs() {OPtr.reset(new OMatrix());}
        ~OMatrix() {}
};

Another option is to just store it in a vector. 另一种选择是将其存储在向量中。

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

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