Должны ли объекты, инициализированные и хранящиеся в другом классе, быть динамически / статически распределенными? - PullRequest
0 голосов
/ 29 августа 2011

Я новичок в C ++, но у меня есть некоторые базовые знания о распределении памяти в C. Я пишу класс Card, в котором хранится номер карты и список объектов класса Activity.

class Card {
    public:
    Card();
    ~Card();
    vector<Activity> activities;
    int cardNo;
}

В настоящее время я инициализирую объект Activity с помощью следующего кода:

Activity a = Activity("a"); 

и вставьте их в вектор, определенный в объекте Card.

Но я обнаружил, что люди склонны инициализировать, используя вместо этого Activity * a = new Activity ("a") (динамическое распределение?), И объекты, объявленные прежним способом (статически распределенные?), Будут освобождены, когда функция объявит их прекращается.

Тогда, если я инициализирую объекты Activity так же, как и раньше, но инициализирую Card, используя способ "new Card ()", возможно ли, что объекты Activity могли быть отменены до освобождения объекта Card? Должен ли я переключиться на использование «new Activity ()» для инициализации объектов, хранящихся в Card?

Ответы [ 3 ]

1 голос
/ 29 августа 2011

Нет, то, что вы делаете, хорошо. Когда вы помещаете объект на vector, создается копия. Поэтому, когда ваша функция возвращается, ваш a уничтожается, но vector, к которому вы добавили его, все еще имеет свою отдельную копию.

Одна из причин, по которой кто-то мог бы динамически выделить экземпляр класса и поместить его в вектор, заключается в том, что копирование объектов этого конкретного класса обходится дорого (а vector делает много копий внутри), и они хотят избежать таким образом, они хранят указатели вместо объектов, так что создаются только копии указателей, а не объектов (что было бы не так дорого). Это все зависит от класса, хотя; как правило, вы можете использовать векторы объектов без проблем с производительностью.

Примечание: ярлык 1 для Activity a = Activity("a"); равен Activity a("a") или лучше, выполните то, что предложил Бенджамин, и выполните activites.push_back(Activity("a")), если вы не выполняете какие-либо операции с Activity перед вами нажмите его.

1 Это на самом деле не ярлык, потому что он делает что-то другое, но для ваших намерений и целей это так.

0 голосов
/ 29 августа 2011

Несколько случаев, когда вам нужны указатели:

  • это может быть NULL вместо какого-то фиктивного состояния
  • полиморфно
  • общий, не эксклюзивный для класса
  • существует циклическая зависимость или рекурсия, которая предотвращает прямую переменную-член

В этом конкретном случае, как и в большинстве контейнеров STL, переменные-члены предпочтительнее, чем указатели на элементы.

0 голосов
/ 29 августа 2011

"Но я обнаружил, что люди склонны инициализировать, используя вместо этого Activity * a = new Activity (" a ") (динамическое распределение?)"

Какие люди?Они делают это неправильно.Вы делаете это правильно, вроде.Вы можете просто сделать это вместо:

activities.push_back(Activity("a"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...