2014-01-21 7 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()); копии A в b1 тоже вместо перемещения.

Благодарим за помощь.

EDIT: Чтобы ответить на тех, кто путаются, как я только был:

Me: Я просто понял, что когда instanciating b1 него требовалось A::A() конструктор. Я думал, что это будет как «нуль» или что-то, если я создал b1 без создания экземпляра _a.

Zac Howland: @SanjamX Теперь я вижу ваше замешательство. В управляемых языках (большинство) все является указателем, поэтому, если вы его не создаете (например, A a вместо A a = new A()), это всего лишь нулевой указатель. В C/C++, если вы объявляете что-то как 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(); 

Из-за предыдущей ситуации 2 строки, приведенные выше, дадут вам ошибку компилятора.

«Перемещение», о котором вы спрашиваете, на самом деле будет копией (в данном случае). Вы можете использовать семантику перемещения C++ 11 для выполнения фактического перемещения, но это совершенно необязательно для текущего кода. В качестве альтернативы вы можете изменить свой класс, чтобы сделать ход, используя указатели (которые потенциально могут быть полезны), которые будут использовать std::unique_ptr<A> _a, а не A _a.

+0

«move» from std будет менять значения между тем, что находится в b1 :: _ a и b2 :: _ a? Что, если я хочу удалить то, что есть b2 :: _ a? – Majid

+1

@SanjamX На самом деле ничего не значит _'swap'_ !! В противном случае объявить соответствующий конструктор перемещения. –

+0

@SanjamX Нет, он не поменяет их. Если вы переместите его, он будет перемещен. Я думаю, вам будет лучше использовать решение 'std :: unique_ptr', так как нет необходимости переместить что-либо в вашем текущем коде. –

Смежные вопросы