0

I wrote a template class with one int member and a generic-typed pointer member. The pointer member will be used as an array, and it will store sideCount amount of elements. When instantiating an object, it will take an int value for sideCount and an array of any type that is the size of sideCount and is already initialized with values.

I wrote 2 versions of this class. For the first one, I didn't specifically allocate any memory for my pointer member:

template <class T>
class die_v1
{
private:
    int sideCount;
    T* valuesOfSides;
public:
    die_v1() : sideCount(0), valuesOfSides(nullptr) {}
    die_v1(int sc, T* vos) : sideCount(sc), valuesOfSides(vos) {}
};

For the second one, I dynamically allocated memory for valuesOfSides using new[]:

template <class T>
class die_v2
{
private:
    int sideCount;
    T* valuesOfSides;
public:
    die_v2(int sc, T* vos) : sideCount(sc)
    {
        valuesOfSides = new T[sideCount];

        for (int i = 0; i < sideCount; ++i)
            valuesOfSides[i] = vos[i];
    }

    ~die_v2() { delete[] valuesOfSides; }
};

My question is, do I need to specifically allocate memory for valuesOfSides as I did in the second version?

The reason I am asking this is, for the second version, I know exactly what is going on. I'm allocating memory for valuesOfSides with the size of sideCount and I'm assigning it with the data in the parameter array. For the first version, I just know it works when I initialize it with the member initializer list, does it have a size? If so, is it the size of the array that I sent from main()? It looks more clean and efficient since I don't have to allocate any memory, and I don't need a destructor.

Does the die_v2 provide any code stability compared to die_v1? Or is it the same thing with more steps?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
nyms1
  • 61
  • 7
  • 3
    For the pointer to be useful, sooner or latter it's got to point at something, but you may not have to allocate what it point at. But if you do allocate it, [make sure you own it](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers). – user4581301 May 03 '22 at 20:18
  • 3
    The least of your worries will be allocation. The far bigger issue is that your `die_v2` class has wrong copy-semantics, i.e. the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) is violated. – PaulMcKenzie May 03 '22 at 20:18
  • 4
    vector would be way better than manually managed array – pm100 May 03 '22 at 20:19
  • 2
    Also using vector removes the *rule of 3* issue mentioned in my first comment. – PaulMcKenzie May 03 '22 at 20:20
  • 3
    The two class have completely different meaning. `die_v1` is a view on some other contiguous container while `die_v2` makes a complete copy of the data. It isn't a question of which is better, it's a question of what do you want your `class` to do? – François Andrieux May 03 '22 at 20:21
  • 1
    Once it's corrected to fully observe the Rule of Three, `die_v2` has the advantage of being able to outlive the argument provided for `vos` . A very common mistake is allow an object to expire before everyone pointing at it has finished using it. This can lead to very interesting bugs with unpredictable behaviour. On the other hand it is slower and consumes more memory. Which is better depends on usage. – user4581301 May 03 '22 at 20:23
  • 2
    [I think your die_v2 just exploded](http://coliru.stacked-crooked.com/a/da024a44ddfd0209). – PaulMcKenzie May 03 '22 at 20:24
  • 1
    Don't use raw pointers. Use RAII types like smart pointers or containers, or better, no pointers at all. And if you really want to use pointers, use the rule of five. – JHBonarius May 03 '22 at 20:24
  • Oh boy, this turned out more difficult than I anticipated, I didn't even knew my code was erroneous, right now Im tyring to understand what rule 3 is. – nyms1 May 03 '22 at 20:28
  • 1
    @nyms1 -- It becomes very simple if you used `std::vector` instead of `T*`. Otherwise, the link to the rule of 3 -- go to the **Managing resources** section, and you will see right away why your code fails. The example there looks almost exactly like your code. In addition, if you used `std::vector`, you wouldn't need that `sideCount` member variable, since a `std::vector` knows its size already by using the `size()` member function. – PaulMcKenzie May 03 '22 at 20:30
  • @PaulMcKenzie thank you for the link, Im fairly new to c++ so I dont even know what vectors are, for the time being I think I will focus on getting what I "know" straight. Before moving onto new topics. – nyms1 May 03 '22 at 20:33
  • 1
    @nyms1 A vector is simply a class that does exactly what your `new[]` and `delete[]` are doing. The difference is the vector does it safely, efficiently, and you get member functions that handle the buffer thrown in as bonuses. But why do you not know about `std::vector`, but attempting to write non-beginner template code? The vector has been around C++ for 24 years now -- it should have been taught very early. – PaulMcKenzie May 03 '22 at 20:36
  • 1
    C++ is, in my opinion, taught backwards. Instructors generally teach C++ from the same lesson plans they taught C from (and the C plans were likely derived from Pascal and the Pascal plans from ... Turtles all the way down). Learn to use the Standard library early so you don't waste time you could be spending getting a grip on good style, design skills, and basic logic reinventing the wheel. Once you know how to write good code, then learn low-level programming as well. Knowing how the tools work at the lower levels allows you to write better high-level programs. – user4581301 May 03 '22 at 20:46
  • @PaulMcKenzie I'm not sure myself, I'm simply following our syllabus + playing around with the practice codes that are given and trying things out for myself to have a better understanding of the concepts that's why I wrote 2 versions of the same example. Before vectors, there are encapsulation, polymorphism, inheritance, memory allocation(stack, heap), copy constructors topics then vectors. Do you think I should start learning about vectors myself before those? – nyms1 May 03 '22 at 20:53
  • @user4581301 That plan makes sense, I always had a curiosity about how things played out at lower levels will definitely learn about lower-level languages after I complete the syllabus! – nyms1 May 03 '22 at 20:55
  • 1
    I'm not talking about lower languages, I'm talking about the lower levels of *C++*. All by itself, C++ goes very deep. Think of it like a stack of building blocks where each building block can be taken apart to get at even finer-grained stuff. My point is `new`/`delete` and the care and feeding thereof is an advanced topic, something that shouldn't, again my opinion, show up before the end of the introductory material. I'm a huge fan of concentrating on one issue at a time, and by comingling low-level scaffolding with the basics of writing a program that works sensibly just wastes time. – user4581301 May 03 '22 at 21:27

0 Answers0