Как решить, должны ли атрибуты класса быть указателем или значением при использовании композиции в C ++? - PullRequest
2 голосов
/ 24 февраля 2012

См. Этот пример.

В университетском классе есть директор и много учеников, поэтому мой класс будет таким

a)

class University {
    Director d;
    Student list[1000];
};

или

b)

class University {
    Director* d;
    Student* list[1000];
};

Моя проблема в том, как решить, должны ли атрибуты класса быть указателем или значением.

Ответы [ 7 ]

3 голосов
/ 24 февраля 2012

Большинство других ответов сосредоточены на деталях кучи и непосредственного сдерживания (или вообще не предоставляют никакой информации, например, используйте указатели, когда вы хотите указатели ... Вместо того, чтобы фокусироваться на деталях, рассмотритеОбщий дизайн приложения.

Первый вопрос будет касаться владения. В вашей программе те ученики и директор принадлежат классу или существуют вне рамок класса.В большинстве простых приложений объекты могут существовать только внутри класса, но в других более сложных схемах учащиеся могут принадлежать к школе и иметь ссылки только в классе (или директор может также преподавать некоторые курсы другим классам).Если классу принадлежат объекты, композиция будет лучшим подходом: держать директора непосредственно в качестве члена, а студентов внутри контейнера, который непосредственно принадлежит классу (я бы порекомендовал вектор, который является безопасным выбором для большинстваслучаи).

Если объекты не относятся к классус, то вы скорее будете использовать агрегацию.Кто бы ни владел объектом, он должен будет управлять временем жизни и решать, как хранить реальные объекты, а класс будет содержать только ссылки (в общем смысле) на эти объекты.Все становится сложнее, поскольку есть больше вариантов.Если право собственности может быть передано, то вы бы динамически распределяли объекты и удерживали указатели, где вы должны прочитать умные указатели , чтобы память управлялась для вас.

Если владение не меняется иСрок жизни учеников / директора гарантированно будет превышать срок жизни класса, вы можете использовать ссылки.В частности для режиссера.В случае студентов это будет сложнее, так как у вас не может быть контейнеров с простыми ссылками, поэтому решением могут быть все еще указатели, вектор указателей.Другая проблема, связанная со ссылками, заключается в том, что они не могут быть повторно установлены, что означает, что если вы удерживаете ссылку на директора, директор класса будет фиксированным на протяжении всего времени жизни класса, и вы не сможете заменить его.

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

1 голос
/ 24 февраля 2012

как решить, должны ли атрибуты класса быть указателем или значением

Я бы в основном выбрал значение (т.е. объект). В некоторых особых случаях я выберу указатель (может быть, умный!). Для вашего случая будет достаточно:

class University {
    Director d;
    std::vector<Student> list;    
public:
    University () { list.reserve(1000); }
};

Преимущество наличия объекта в том, что вам не нужно выполнять собственную сборку мусора, поскольку управление ресурсами будет автоматическим.

Указатели можно использовать, когда вы хотите изменить владельца ресурса (аналогично мелкому копированию), в то же время избегая дорогих копий, созданных во время копирования или назначения. Во всех других случаях используйте объекты (то есть значение) для композиции.

1 голос
/ 24 февраля 2012

Проблема здесь в следующем: где находится хранилище для этих переменных-членов?Иногда имеет смысл, чтобы часть данных была размещена где-то еще и использовалась в других местах.В этом случае указатель может иметь смысл (вместо использования конструктора копирования).Однако обычно это не так (особенно с инкапсуляцией).Затем вы хотите сохранить данные члена в классе.В таком случае, и ваш пример выглядит так, что вы не хотите использовать указатель.

0 голосов
/ 24 февраля 2012

Вот для чего я бы:

 class University {
        Director d;
        Student **list;
    };

Даже если это большая часть личного вопроса.Я думаю, что использование указателя на указатель лучше в этом случае, если вы знаете, с чем играете!

Я не думаю, что массив указателей является хорошим выбором.Если вы не хотите указатели, используйте Значение

0 голосов
/ 24 февраля 2012

В обоих случаях атрибуты класса сохраняются по значению, просто случается, что во втором случае эти значения являются указателями.

Используйте указатели, когда вы хотите указатели, используйте не указатели, когда вы нехочу указатели.Это полностью зависит от желаемой семантики класса, который вы пишете.

0 голосов
/ 24 февраля 2012

На самом деле есть три варианта
1. Объект
2. Ссылка
3. Указатель

Это часть проекта / архитектора .. о том, что использовать для какого объекта.В основном .. решающими критериями будут жизненные циклы объектов и контейнеров.

0 голосов
/ 24 февраля 2012

Ну, это зависит. Указатели следует использовать, когда вы хотите добавить материал в кучу, в то время как это означает, что у вас есть немного больше свободы в том, когда / как вы распределяете память, вам нужно добавить больше кода, чтобы избежать утечек памяти: то есть деструкторов и удаления вещей. Это также позволяет вам легко изменять значения из других функций / классов без необходимости передавать ссылку, просто передайте ее в форме указателя.

Одна очевидная ситуация, когда указатели полностью необходимы, - это объект узла двоичного дерева, поскольку он должен содержать объекты того же типа, что и сам, он должен использовать указатели на эти объекты. IE:

struct Node{
  Node* left;
  Node* right;
  //Other stuff

};

Во многих ситуациях, однако, на ваше усмотрение. Просто отвечайте за свои указатели, если вы их используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...