2014-01-21 160 views
0

我是一個使用V ++的新手,我一直在想一些內存行爲。
我寫了類似的類,導致我的問題。在代碼的評論中寫下的問題是 。內存分配和釋放內存

class A 
{ 
private: 
    int _number; 
public: 
    A(int number) : _number(number) 
    {} 

    const int& getNumber() const 
    { 
     return _number; 
    } 

    void setNumber(const int& number) 
    { 
     _number = number; 
    } 
} 

class B 
{ 
private: 
    A _a; 
    bool _hasA; 

public: 
    B() : _hasA(false) 
    {} 

    B(const A & a) : _a(a), _hasA(true) 
    {} 

    void setA(const A & a) 
    { 
     _a = a; 
    } 

    const A& getA() const 
    { 
     return _a; 
    } 

    const bool hasA() const 
    { 
     return _hasA; 
    } 

    void removeA() 
    { 
     // ?? 
    } 
} 

int main() 
{ 
    A a(5); 

    B b1; // Is the A space allocated even if no value is affected to it ? 
    B b2(a); 

    b1.setA(b2.getA()); // I actually want to move "a" from b2 to b1 without leaving it in b2 
    b1.removeA(); // Do I need to write a removeA() function and how would it be? 
} 

b1.setA(b2.getA());副本Ab1太多,而不是移動它。

感謝您的幫助。

編輯:要回答那些誰弄得像我剛纔是:

我:我只是明白instanciating B1它時所需的A::A()構造。我認爲它會像「空白」或什麼的,如果我創建b1沒有instantiating _a

Zac Howland:@SanjamX我現在看到你的困惑。在託管語言中,(大部分)所有東西都是一個指針,所以如果你沒有實例化它(例如A而不是A a = new A()),它只是一個空指針。在C/C++中,如果將某些內容聲明爲A a,則將其「實例化」到堆棧中。它是一個自動變量,當它超出範圍時將被釋放。但是,你仍然在實例化它。 This question可能會幫助你更好地理解。

+2

你試過編譯它嗎? (提示:它不會編譯,有幾個錯誤)注意:'B b1();'是一個函數聲明(「最令人頭痛的解析」);或者使用C++ 11的'B b1 {};'或者'B b1;'。 – dyp

+1

我沒有看到代碼中的任何一點,它有必要釋放分配的內存?它將在堆棧中完成得很好? –

+0

與b1.setA(b2.getA()); A將被複制到b1。他們會共享相同的指針嗎?我想將A移到b1而不是複製它。換句話說,我希望它從b2中刪除。 – Majid

回答

3
B b1(); 

這並不符合您的想法。它聲明一個函數b1,它不接受參數並返回B

b1.setA(b2.getA()); 
b1.removeA(); 

由於前面的情況,上面的兩行會給你一個編譯器錯誤。

你所問的「移動」實際上是一個副本(在這種情況下)。您可以使用C++ 11移動語義來進行實際移動,但對於當前的代碼來說完全沒有必要。或者,您可以更改班級,使用指針(可能會有用)進行移動 - 這將使用std::unique_ptr<A> _a而不是A _a

+0

std中的「移動」會交換b1 :: _ a和b2 :: _ a之間的值嗎?如果我想刪除什麼是b2 :: _ a,該怎麼辦? – Majid

+1

@SanjamX實際上沒有什麼可以_'swap'_!否則,聲明一個合適的移動構造函數。 –

+0

@SanjamX不,它不會交換它們。如果你移動它,它會移動。我想你會更好地使用'std :: unique_ptr'解決方案,因爲不需要在當前代碼中移動任何內容。 –