ООП: Когда я должен объявлять участников класса динамически? - PullRequest
0 голосов
/ 10 декабря 2018
#include "stdafx.h"
#include <memory>

using namespace std;

class MyClass1
{
public:
    MyClass1(int a, int b, int c, int d) :data1(a), data2(b), data3(c), data4(d) {}
    ~MyClass1() = default;
private:
    int data1;
    int data2;
    int data3;
    int data4;
};

class MyClass2
{
public:
    MyClass2(int a, int b, int c, int d) :data1(a), data2(new int(b)), data3(make_shared<int>(c)), data4(make_unique<int>(d)) {}
    ~MyClass2() { delete data2; }
private:
    int data1;
    int* data2;
    shared_ptr<int> data3;
    unique_ptr<int> data4;
};

int main()
{
    MyClass1 mc1automatic(1, 2, 3, 4); // Case 1 : Every integer allocated on stack
    MyClass2 mc2automatic(1, 2, 3, 4); // Case 2 : Every integer except data1 allocated on heap
    unique_ptr<MyClass1> mc1dynamic = make_unique<MyClass1>(1, 2, 3, 4); // Case 3 : Every integer allocated on heap
    unique_ptr<MyClass2> mc2dynamic = make_unique<MyClass2>(1, 2, 3, 4); // Case 4 : Every integer allocated on heap
    return 0;
}

В этом примере объект, на который указывают и mc1dynamic, и mc2dynamic, динамически распределяет членов своего класса (Каждые данные в MyClass1 и data1 в MyClass2), несмотря на то, что план объявляет их как автоматические переменные.

Если я точно знаю, что объект (MyClass1, в данном случае MyClass2) будет размещен динамически, почему я бы выбрал динамическое объявление членов класса, как я это делал в MyClass2?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

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

0 голосов
/ 10 декабря 2018

Когда я должен динамически объявлять членов класса?

Члены не могут быть "объявлены" динамически.Я предполагаю, что вы хотите спросить, когда выделять динамически.

Вот несколько случаев, когда вы хотите распределить динамически:

  • Время жизни подобъекта не является прямымпривязан к владельцу - например, когда вы хотите иметь общее владение: в этом случае вы захотите использовать общий указатель.
  • Вам нужен межсетевой экран компиляции, чтобы скрыть детали реализации.Шаблон PIMPL гораздо проще реализовать с помощью динамического выделения.Здесь полезен уникальный указатель.
  • sizeof подобъекта очень велик, и вы хотите выделить объект владельца в автоматическом хранилище.Динамическое распределение здесь необходимо, потому что память, доступная для объектов в автоматическом хранилище, обычно ограничена.Уникальный указатель также полезен здесь - если большой член не является массивом, в этом случае векторный контейнер может быть проще.
  • Вы реализуете структуру данных, размер которой определяется во время выполнения.Обратите внимание, что стандартная библиотека предоставляет вам часто используемые структуры данных, и очень редко нужно реализовывать пользовательские структуры.Но если вы это сделаете, уникальный указатель, вероятно, будет полезен.

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


Обратите внимание, что голые владеющие указатели, такие какMyClass2::data2 вряд ли хорошая идея.

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