2016-10-25 75 views
-4

我在想以下創建類的對象的方式有什麼區別。頭文件是:創建類的對象的方法

class NumberRange { 
public: 
    NumberRange(int a, int b); 
    virtual ~NumberRange(); 
    void Print(int a, int b); 
private: 
    int *range_; 
    int size; 
}; 

.cc文件是:

#include <iostream> 
#include "numberrange.h" 
using namespace std; 

NumberRange::NumberRange(int a, int b) { 
    if (a > b) { 
     cout << "a must be equal or less than b" << endl; 
    } 
} 

NumberRange::~NumberRange() { 

} 

void NumberRange::Print(int a, int b) { 
    this->size = b - a + 1; 
    this->range_[0] = a; 
    for (int i = 0; i < this->size; i++) { 
     this->range_[i] = a + i; 
     cout << this->range_[i] << endl; 
    } 
} 

int main() { 
    NumberRange * numberrange = new NumberRange(5, 9); 
    numberrange->Print(5, 9); 
} 

當我使用指針創建一個對象,並編譯該程序。我得到一個錯誤說:[1] 20346 segmentation fault ./numberrange

,但如果我改變的主要功能爲:

int main() { 
    NumberRange numberrange(5,9); 
    numberrange.Print(5,9); 
} 

這將是工作。所以我不知道什麼時候應該用指針來創建一個對象。謝謝!

+0

該對象的其中一個字段是'int * range_'。你永遠不會在構造函數中初始化/分配它,所以在Print函數中使用它將是未定義的行爲。有時它會起作用,有時不起作用。首先解決問題,然後重試。 –

+3

你錯過了分配'range_',那很簡單。所以你調用未定義的行爲。未定義的行爲是......好的......未定義的。 –

+0

如果第二個工作,那只是因爲你運氣好。你訪問'range_'對象而不給它任何存儲,這是未定義的行爲。 – Chad

回答

1

你的程序至少有三個問題。

第一個最明顯的問題是int * range_是一個指向整數的指針,但並不指向任何特別的東西。它只是包含一個隨機存儲器地址。 要改變這種情況,可以爲它分配一個int數組,例如你使用new創建的int數組。 :

range_ = new int [b - a]; 

第二,不太明顯的問題是,你通過a和b兩次你的對象,首先在構造函數和後面的打印方法(最好不要利用方法,順便說一句)。 ++在C++中爲您提供的一件事是面向對象。對象有狀態。如果您希望NumberRange類的對象存儲從3到7的數字,請使用構造函數將它們存儲爲屬性。無需在Print方法中再次傳遞邊界,它可以從屬性中讀取它們。

第三個更不明顯的問題是,在你的例子中,根本不需要存儲數字,因爲你只是想打印它們。

問題二和三相連接。或許你想用數字做更多的事情,而不僅僅是打印它們。所以構造函數要麼存儲a和b,要麼分配一個數組並存儲從a到b的數字。後者的效率較低,但可能稍後想要存儲不相鄰整數的序列。

3

你有一個指針range_在你的類中,你沒有在構造函數中初始化。然後在Print方法中使用它,在兩種情況下都會導致UB。事實上,該程序不會在第二種情況下崩潰並不意味着您的程序是正確的。