簡體   English   中英

想要通過使用構造函數和變量來聲明數組

[英]want to declare arrays by using constructor with variables

class matrix
{

public:

    matrix();
    matrix(int row, int column);
    ~matrix();

private:

    const int DEFAULT_SIZE;

    int size_row, size_column;
    double *entry;
};

// main function
int
main()
{
    //make a matrix of default size
    matrix A;   /* no error */
    delete A;

    //make 5 matrices of default size
    matrix *B = new matrix [5]; /* no error */
    delete [] B;

    //make a matrix of size 15x15
    matrix C(15, 15);   /* no error */
    delete C;

    //make 5 matrices of size 15x15
    matrix *D = new matrix(15, 15) [5]; /* compile error !! */


    return 0;
}



//Define functions

matrix::matrix() : DEFAULT_SIZE(10)
{
    size_row = DEFAULT_SIZE;
    size_column = DEFAULT_SIZE;

    entry = new double [size_row*size_column];
}

matrix::matrix(int row, int column) : DEFAULT_SIZE(10)
{
    size_row = row;
    size_column = column;

    entry = new double [size_row*size_column];
}

matrix::~matrix()
{
    delete [] entry;
}

我正在研究構造函數。 我想通過使用構造函數和變量來聲明數組。 您可以更正我的代碼行嗎?

請查看下面的行:'//制作5個尺寸為15x15的矩陣'

另外,在這種情況下,如何使用析構函數?

要制作由5個元素組成的數組,每個元素都用(15,15)構造,可以在C ++ 11中執行以下操作:

matrix* D = new matrix[5]{
    {15,15}, {15,15}, {15,15}, {15,15}, {15,15}
};

但是使用vector會更加簡單:

std::vector<matrix> D(5, {15,15});        // C++11
std::vector<matrix> D(5, matrix(15,15));  // pre-C++11

看完您的源代碼之后,這就是我所看到的! 在您的私有成員的類中,行和列的大小不應為int類型,而應為unsigned int類型。 它們應為無符號int的原因是,沒有默認值的int默認為帶符號值,這意味着它可以具有負數。 對於沒有意義的矩陣中的行和列的數量。 使用無符號整數值時,其范圍是無符號整數的[0,max_value]。 還要注意的另一件事是,如果有人為行或列的大小或兩者都輸入了0,該怎么辦? 這樣您將仍然沒有有效的矩陣。 這里需要做一點邏輯。 如果有人為此輸入0,則必須決定默認行為是什么。 您是否要使用默認值10? 同樣,1x1的值也沒有意義! 現在您可以有1x4或4x1,那么它們將不完全是一個矩陣,而是按順序是行或列主向量的向量。 坦白地說,您從基本構造函數獲得的默認矩陣大小(不帶任何參數)應為2x2。 如果用戶為任何一個參數指定1,則另一個參數應大於1。同樣,此處不需要2個構造函數,這是重復的代碼,僅用1個構造函數即可完成。 同樣也不需要調用析構函數,當此類對象超出范圍時,它將自動被調用。

對於矩陣,您是否認為元素應該是公共的以便於訪問? 現在,您的(元素)數組是私有的,這意味着沒有外部類可以訪問它們,如果這是您想要的行為,那么您將需要函數來訪問它們並在需要更改值時進行設置。

根據您的類實現,我在這里向您展示了我上面提到的更改。

#include <vector>
#include <array>

class Matrix {
private:
    const unsigned int DEFAULT_SIZE;
    unsigned int size_row, size_column;
    double* elements;

public:
    explicit Matrix( unsigned int row = 0; unsigned int column = 0 );
    ~Matrix();

    // Copy Constructor
    Matrix( const Matrix& c );
    // Operator = Needed
    Matrix& operator=( const Matrix& c );

}; // Matrix

Matrix::Matrix( unsigned int row, unsigned int column ) : DEFAULT_SIZE(2) {
    // Check if both are 0 Or both are 1 - use default sizes
    if ( (row == 0 && column == 0) ||
         (row == 1 && column == 1) ) {
        row    = DEFAULT_SIZE;
        column = DEFAULT_SIZE;        
    } 

    // Check [Row,Column] For [0,1] && [1,0]
    if ( row == 0 && column == 1 ) { 
        row    = 1;
        column = DEFAULT_SIZE;

    } else if ( row == 1 && column == 0 ) {
        row    = DEFAULT_SIZE;
        column = 1;            
    }

    size_row    = row;
    size_column = column;   

    element = new double[size_row * size_column];    
} // Matrix

Matrix::~Matrix() {
   delete [] elements
} // ~Matrix

Matrix::Matrix( const Matrix& c ) : DEFAULT(2) {
    this->size_row    = c.size_row;
    this->size_column = c.size_column;
    this->element     = c.element;
} // Matrix(copy)

Matrix& Matrix::operator=( const Matrix& c ) {
    // Assignment Can Only Happen If Both Matrices Are Of The Same Dimensions:
    // You can not set a 4x3 = 6x9 for this does not make sense
    if ( (this->size_row    == c.size_row) &&
         (this->size_column == c.size_column) ) {

          this->element     = c.element;
    return *this;
} // operator=

至於您主要功能中的代碼,我看到一些錯誤需要修復。 前兩行:

Matrix A;
delete A;

您正在聲明矩陣A; 然后在下一行上,您在A上調用delete。這是您的第一個錯誤:A是Matrix的實例。 這是一個局部堆棧變量,它屬於main函數的作用域。 無需為此調用delete! 當您的Matrix(A)實例超出范圍時,將在后台為您隱式調用Matrix ::〜Matrix(),因此無需調用它。

接下來的兩行代碼:

Matrix* B = new Matrix[5];
delete [] B; 

這兩個是正確的,這里沒有問題。 您的實例B是指向類型對象Matrix的指針,由於這里使用new,因此它是在堆上創建的,並且因為您有[5] B不僅是指向該類型的指針,而且還是堆上指向第一個地址的指針您動態分配的數組。 然后使用正確的B上的[]運算符調用delete。

接下來的兩行代碼:

Matrix C(15,15);
delete C;

您正在堆棧上聲明一個名為C的Matrix對象的實例,現在您正在使用定義的構造函數。 再次在第二行,無需在C上調用delete。

至於您的最后兩行代碼,這並不像想做想要的那么簡單,但並不是那么簡單。 為了創建所有默認大小為15x15的矩陣的動態數組,需要做更多的工作。 為了正確執行此操作,您可以從類實現中看到我添加了一個Copy Constructor和一個重載=運算符。 要實現此目的,需要三個步驟。

// First Step - Create A Single Stack Instance With Size [15,15]
Matrix D = Matrix( 15, 15 );  // This Will Be Used Later To Populate Your Array
// Second Step - Create An Array of 5 Matrices On The Heap
Matrix* E = new Matrix[5]; // Right Now All Five Are Using Default Size 2x2.

// Step Three Now We Update Them Using Our operator=()
for ( unsigned int i = 0; i < 5; i++ ) {
    E[i] = D;
}
// Then Delete the Array
delete [] E; // Only Need To Delete E

但是,這將不起作用:由於我們的operator =()的定義方式! 那么我們如何實現這一目標呢? 有兩種方法,兩種方法都可以。 因此,您可以刪除Matrix E,for循環和delete [] E行。 離開矩陣D,將是需要的!

第一種比較容易:如果您注意到我在這種情況下同時包含了STL的vector和array,則將使用vector類,因為它是最常用的。

// We already have: Matrix D = Matrix( 15, 15 );
// You Want an Array of 5
std::vector<Matrix>  vMatrices;  // This will create a vector of stack Matrices but at first it will be "EMPTY"
for ( unsigned int i = 0; i < 5; i++ ) {
     vMatrices.push_back( D );
}

// Now You Have A vector of 5 Matrices.

// If You Want Vector of Pointers
std::vector<Matrix*> vpMatrices; 
for ( unsigned int i = 0; i < 5; i++ ) {
    vpMatrices.push_back( &D );
}

// To clean up your vectors you can simply do
vMatrices.clear();
vpMatrices.clear(); 

// The Other Way Would Be To Use std::array but it is less commonly used.
// If You know you will only ever need a set amount this works good
std::array<Matrix, 5> aMatrices;
for ( unsigned int i = 0; i < 5; i++ ) {
    aMatrices.at(i) = D;
}

// For Holding Pointers
std::array<Matrix*, 5> apMatrices;
for ( unsigned int i = 0; i < 5; i++ ) {
    apMatrices.at(i) = &D;
}

// To Clean Up std::array To Be Honest Not really sure for I do not use them
// But using it here just as an illustration that there are plenty of predefined containers
// to use to hold multiple elements of the same data type.

關於類的最后一點是,您要創建矩陣的大小並根據大小定義元素數組,但是由於所有內容都是私有的,因此無法填充或訪問它。 保持私有性意味着您必須實現函數才能做到這一點,並考慮矩陣的性質,以便它們“存儲”數據或“函數調用”,或者作為計算和運算的數學對象。 您不希望附加功能的開銷會降低性能。 保留行和列的大小私有沒有錯,因為一旦定義了它們,就無需在類外部訪問它們。 但是代表您的MxN矩陣的一維數組應該公開定義。 另外,您還應該定義operator []。

如果您想了解基本數學庫如何實現矩陣,請查看為與OpenGL着色器語言GLSL配合使用而編寫的GLM數學庫。 該庫是僅標題的庫。 無需鏈接或包含* .dlls或* .libs。 您需要做的就是將其存儲到計算機上的文件夾中,並設置系統使其具有指向其主文件夾的環境變量。 然后在IDE中,如果您使用的是VS,則在項目屬性的其他包含部分中要做的就是使用定義的環境變量。 這是使用它! 但是,只需查看其內容,就可以將其下載到任何文件夾並打開任何* .h文件。 然后,您將看到他們如何實現Matrix類! 您會注意到它們是模板類型,並且具有預定義的矩陣類型,例如mat2x2,mat2x3,mat2x4,mat3x2,mat3x3,mat3x4,mat4x2,mat4x3和mat4x4。 這符合編寫專注於2D和3D圖形的程序和着色器的本質,因此所需的最小值是2x2,真正需要的最大值是4x4。 它們還具有定義為不同大小的向量類,並且可以從不同大小的向量構造矩陣。 但這應作為指導。 這是他們的鏈接GLM

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM