0

I'm learning C++ and especially OO Programming.

My program use pointers to deal with Dynamic memory allocation.

While creating my default constructor, I was boring about repeat myself with

myInt = new int;
myOtherInt = new int; 

etc..

So my question is : is there a way to write something like :

myInt, myOtherInt = new int;

Here's my constructor code :

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);

}
Laurent
  • 15
  • 4
  • 13
    "My program use pointers to deal with Dynamic memory allocation." does it have to? Instead of your class consisting of `std::string *` and `std::vector <>*`, can it just hold `std::string` and `std::vector`? These objects handle dynamic memory allocation themselves, so we don't have to. – JohnFilleau Feb 25 '20 at 20:57
  • 12
    I'm 99.9% certain you don't need those pointers. Have a look at this for how a constructor should look: https://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor – NathanOliver Feb 25 '20 at 20:58
  • 5
    `myInt = new int;` should be something you almost never do. Same with `intro = new string;` – drescherjm Feb 25 '20 at 21:00
  • 5
    You should almost never use `new` directly (except potentially as argument to e.g. `std::shared_ptr` or `std::unique_ptr` members). The examples you are showing here in particular are clearly wrong. See [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new). If your instructional material taught you to write C++ like this, then I suggest you stop using that material and look at one of the [recommended C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. – walnut Feb 25 '20 at 21:01
  • No `myInt, myOtherInt = new int;` won't work. Look up what the comma operator does because it does not do what you would want. – drescherjm Feb 25 '20 at 21:03
  • 6
    C++ is not Java. `new` may be routine in Java, but it should be avoided or minimized in C++, for reasons that walnut pointed to. – jjramsey Feb 25 '20 at 21:05
  • @John no it does not i’m learning and so I write this only for learning pointers and be fine with them. – Laurent Feb 25 '20 at 21:11
  • 3
    @Laurent while it's certainly something you CAN be learning, one of the features of C++ is how rarely you need to work with dynamic memory allocation. To answer your question, I'd steer away from a faster way to write "new string" over and over again at the very least so it leaves a bad taste in your mouth. – JohnFilleau Feb 25 '20 at 21:13
  • @NathanOliver the same I answer for John it's just learning how pointers works and I actually don't need them; – Laurent Feb 25 '20 at 21:19
  • @walnut Thanks a lot for the links it's very helpfull. I was learning on Udemy and with Bjarne Stourstrup book. – Laurent Feb 25 '20 at 21:19
  • Learn about the rule of 3 / 5 / 0. If you are using pointers in your classes you will need to follow the rule of 3 or 5 instead of the rule of 0. [https://en.cppreference.com/w/cpp/language/rule_of_three](https://en.cppreference.com/w/cpp/language/rule_of_three) – drescherjm Feb 26 '20 at 12:21

3 Answers3

2

There is no shortcut for allocating multiple variables from dynamic memory.

The functions for allocating memory return a single memory address (pointer). Each variable should have its own, unique, location in memory.

The syntax of the C++ language would need to change in order to support the dynamic memory functions returning multiple addresses (pointers).

One recommendation is to reduce the quantity of memory allocations. Ask yourself, "Do I really need to allocate from dynamic memory?" before allocating from dynamic memory.

Thomas Matthews
  • 52,985
  • 12
  • 85
  • 144
0

Is there a way to write something like :

myInt, myOtherInt = new int;

Yes, two ways. But the first is more general than what you specifically asked for...

1. Prefer value-types over reference-types

If you don't know what these are: Value types and Reference Types (Wikipedia).

In some programming languages, almost all of your variables, function parameters, class fields, etc - are references. A prominent example of this is Java. But in C++ - especially these days - we prefer values to references unless there's a good reason not to use values directly. Value semantics are commonly used and well-supported in the language, and most work with them is easier. See also:

Why are pointers not recommended when coding with C++11

Specifically, that means that, when defining a struct or a class, we'll give it non-pointer members. In your case:

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
}

Now, I'm not saying this is necessarily the best possible definition or that it fits all your needs. But if you define it this way, you get:

  • No need to use new, ever.
  • No need to delete anything.
  • No chance of memory leaks (due to this class)

2. Otherwise, use std::unique_ptr's

The std::unique_ptr<T> class lets you avoid having to manage memory yourself - it takes care of that. So if you make your members std::unique_ptr's, you can initialize the value they point to using get(), e.g.:

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
}
einpoklum
  • 86,754
  • 39
  • 223
  • 453
-1

First Pre Answer Suggestion: don't do it.

Second Pre Answer Suggestion: avoid self-managed memory allocation/deallocation and use STL containers and/or smart pointers (std::unique_ptr, std::shared_ptr, etc.) instead

Answer: no, as far I know you can't write something as

int * myInt, myOtherInt = new int;

that allocate both variables (with different allocated pointers).

But you can wrap the pointers in a class or struct that automatically allocate the contained pointer (and, maybe, destroy it in the destructor).

Just for fun... if you write a wrapper as follows

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

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

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

   ~wrappPnt ()
    { delete pnt; }
 };

you can write your Annonce this way

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);
    }
 };

First Post Answer Suggestion: don't do it.

Second Post Answer Suggestion: avoid self-managed memory allocation/deallocation and use STL containers and/or smart pointers (std::unique_ptr, std::shared_ptr, etc.) instead

max66
  • 60,491
  • 9
  • 65
  • 95