C ++ Какой синтаксис для избежания дублирования объявлений? - PullRequest
1 голос
/ 25 февраля 2020

Я изучаю C ++ и особенно программирование на OO.

Моя программа использует указатели для распределения памяти Dynami c.

При создании конструктора по умолчанию мне было скучно повторять я с

myInt = new int;
myOtherInt = new int; 

et c ..

Итак, мой вопрос: есть ли способ написать что-то вроде:

myInt, myOtherInt = new int;

Вот мой код конструктора :

Annonce::Annonce(string Titre, long double Prix, string Intro, string Description, vector<vector<string>> ImgUrls) {

    titre = new string;
    intro = new string;
    description = new string;
    imgUrls = new vector<vector<string>>;
    prix = new long double;

    id = new size_t;
    *id = nbAnnonces;

    *titre = std::move(Titre);
    *prix = Prix;
    *intro = std::move(Intro);
    *description = std::move(Description);
    *imgUrls = std::move(ImgUrls);

}

Ответы [ 3 ]

2 голосов
/ 26 февраля 2020

Нет ярлыка для выделения нескольких переменных из динамической c памяти.

Функции для выделения памяти возвращают один адрес памяти (указатель). Каждая переменная должна иметь свое уникальное местоположение в памяти.

Необходимо изменить синтаксис языка C ++ для поддержки динамических функций памяти c, возвращающих несколько адресов (указателей).

Одной из рекомендаций является уменьшение количества выделяемой памяти. Спросите себя: «Мне действительно нужно выделять из динамической памяти c?» перед выделением из динамической c памяти.

0 голосов
/ 26 февраля 2020

Есть ли способ написать что-то вроде:

myInt, myOtherInt = new int;

Да, двумя способами. Но первое более общее, чем то, что вы специально просили ...

1. Предпочитайте типы значений ссылочным типам

Если вы не знаете, что это: Типы значений и ссылочные типы (Википедия).

В некоторых языках программирования почти все ваши переменные, параметры функций, поля классов и т. д. c - это ссылки. Ярким примером этого является Java. Но в C ++ - особенно в наши дни - мы предпочитаем значения ссылкам, если нет веской причины не использовать значения напрямую. Семантика значений обычно используется и поддерживается в языке, и большинство работать с ними проще. См. Также:

Почему указатели не рекомендуются при кодировании на C ++ 11

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

class Announcement {
public:
    using url_type = std::string; // perhaps use a URL library?
    using image_urls_container_type = std::unoredered_set<url_type>;
        // I'm guessing the URLs aren't really ordered

    std::string title;
    std::string introduction;
    std::string description;
    std::vector<image_urls_container_type> image_urls;
        // Are the images really a sequence of indices? Shouldn't this be something like
        // std::unordered_map<image_id_type,image_urls_container_type> image_urls ?
    long double prize;
    std::size_t id;

    Announcement() = delete;
    // constructors here, if you like
}

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

  • Нет необходимости использовать new, никогда.
  • Нет необходимости удалять что-либо.
  • Нет шансов утечек памяти (из-за этого класса)

2. В противном случае используйте std::unique_ptr

Класс std::unique_ptr<T> позволяет вам избежать необходимости управлять памятью самостоятельно - он позаботится об этом. Поэтому, если вы сделаете своих членов std::unique_ptr, вы можете инициализировать значение, на которое они указывают, используя get(), например:

void foo(int x) {
    auto p = std::make_unique<p>();
    p.get() = x;
    // do stuff with p

    // ...

    // no need to delete p at the end of the function
}
0 голосов
/ 26 февраля 2020

Предложение по первому предварительному ответу: не делайте этого.

Предложение по второму предварительному ответу: избегайте самостоятельного выделения / освобождения памяти и используйте контейнеры STL и / или интеллектуальные указатели (std::unique_ptr, std::shared_ptr , et c.) вместо

Ответ: нет, насколько я знаю, вы не можете написать что-то вроде

int * myInt, myOtherInt = new int;

, которое выделяет обе переменные (с разными выделенными указателями).

Но вы можете заключить указатели в класс или структуру, которые автоматически выделяют содержащийся указатель (и, возможно, уничтожают его в деструкторе).

Просто для удовольствия ... если вы пишете Обертка выглядит следующим образом:

template <typename T>
struct wrappPnt
 {
   T * pnt = new T{};

   T & operator * ()
    { return *pnt; }

   T const & operator * () const
    { return *pnt; }

   ~wrappPnt ()
    { delete pnt; }
 };

Вы можете написать свой Annonce таким образом

struct Annonce
 {
   wrappPnt<std::string>  titre, intro, description;
   wrappPnt<std::vector<std::vector<std::string>>> imgUrls;
   wrappPnt<long double>  prix;


   Annonce (std::string Titre, long double Prix, std::string Intro,
            std::string Description,
            std::vector<std::vector<std::string>> ImgUrls)
    {
      *titre = std::move(Titre);
      *prix = Prix;
      *intro = std::move(Intro);
      *description = std::move(Description);
      *imgUrls = std::move(ImgUrls);
    }
 };

Первое сообщение Ответ Предложение: не делайте этого.

Второе сообщение Ответ Предложение: избегайте самостоятельного выделения / освобождения памяти и используйте контейнеры STL и / или умные указатели (std::unique_ptr, std::shared_ptr, et c.) Вместо

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