0
class Vect {
    public:
        Vect(int n);
        ~Vect();
        Vect(const Vect& original);
    private:
        int* data;
        int size;
};

Vect::Vect(int n) {
     size = n;
     data = new int[n];
}

Vect::~Vect() {
    delete [] data;
}

Vect::Vect(const Vect& original) {
    size = original.size;
    data = new int[size];

    for (int i = 0; i < size; ++i) {
        data[i] = original.data[i];
    }
}

#include <bits/stdc++.h>

using namespace std;

int main(void) {
    Vect a(100);
    Vect b = a;
    Vect c;
    c = a;
    return 0;
}

I have a Vect class now, in main I created a Vect object that variable c holds, what will be the default size of c.size ?? Or It won't have any default? If it does not have a default value then how does b have 100 (as in a.size is now equals b.size)?

afrid18
  • 13
  • 3
  • 3
    Since there are no default constructor, there won't be a way for an instance of `Vect` to have some sort of defaults for any of its data members. The code won't compile due to no matching function call. – rawrex Jul 09 '21 at 07:06
  • do you mean "default value of an int variable" ? – 463035818_is_not_an_ai Jul 09 '21 at 07:08
  • Non-class members (like `int` and `int *`) don't have default values. If they are not initialized they have inderterminate values and using these causes undefined behavior. – Lukas-T Jul 09 '21 at 07:08
  • How can I have a default value to initialize ```Vect c;``` – afrid18 Jul 09 '21 at 07:11
  • 3
    Even if you add a default constructor, this code still doesn't comply with rule-of-three, as `c = a;` is copy-assignment, which is not user-defined and therefore default-provided (i.e. member copy, which will ultimately lead to a potential memory leak after assignment and double-delete at destruction-time). – WhozCraig Jul 09 '21 at 07:12
  • 4
    On an unrelated issue please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) On a more related note, please get [some good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to read and learn all the details about constructors and "default values" that you're wondering about. – Some programmer dude Jul 09 '21 at 07:13
  • This code won't compile. – user253751 Jul 09 '21 at 09:22

2 Answers2

4

What will be the default size of c.size ??

There is no default value except if you provide one. You should have a default constructor if you want to cover it (otherwise using uninitialized variable is undefined behaviour).

For example:

Vect::Vect() : data(nullptr), size(0)
{}

If it does not have a default value then how does b have 100 ?

Actually, when you write Vect b = a;, it is equivalent as Vect b(a);. In other words, the copy constructor is called (this is copy-initialization).

However, when you write:

Vect c;
c = a;

This is a copy-assignment. And you didn't provide one which is a problem because you need to handle the dynamic allocation of the data member (prevent self-assignment, deallocate if not nullptr and then reallocate with the new content), etc...
You should define the operator=() for the Vect class for your program to be well-formed.

Fareanor
  • 5,900
  • 2
  • 11
  • 37
1

To answer your question: There is no default value of Vect::size unless you provide a default one in the class declaration, like

int size = 0;

If you do not initialize Vect::size you incur in undefined behavior.

Further, this code has a lot of problems, and in fact it does not compile.

Essential problems:

  • There is no constructor of Vect with no parameters, and there is not implicitly declared default constructor because you define Vect::Vect(int n). Hence the line Vect c; cannot compile.

  • The code c = a does not call your copy constructor Vect::Vect(const Vect& original), because the variable c already exists (assuming you have fixed the problem above). It does, instead, call the implicitly defined copy assignment operator, which you have not explicitly defined. This however just copies the member variables, thus it does not have the "right" logic since, after such a copy, both c.data and a.data point to the same area of memory. They are not a "copy", and so when a and c go out of scope, the allocated memory is freed twice (crashing the program). You need to define a correct copy-assignment operator Vect::operator=.

Other points:

francesco
  • 7,189
  • 7
  • 22
  • 49