Member variables initialization with new keyword in c++ - c++

class Graph {
private:
int n;
Head* array;
Graph(int n)
{
this->n = n;
array = new Head[n];
for (int i = 0; i < n; i++)
{
array[i].head->vertex = i;
}
}
};
When the first Head* array is being declared, it is being done in the stack. Then again it is being allocated to the heap using the new keyword inside the constructor.
I want to understand if this is the same as if we wrote: Head* array = new Head[n]; And if so then is this a standard way of declaring member variables in a class? Is it also because when objects are created constructors are invoked first, so member variables are not set if they are not in the constructor?

Related

How to delete dynamic allocated array in c++?

I got stuck with deleting an dynamically allocated array of int.
I've got a destructor, where I'm trying to use a loop for to delete all elements of array and finally delete it.
I have code on http://rextester.com/OTPPRQ8349
Thanks!
class MyClass
{
public:
int _a;
int* c;
int fRozmiar;
static int fIlosc;
MyClass() //default constructor
{
_a=0;
c = new int [9];
for(int i = 0; i<=9; i++)
{
c[i] = 1;
}
fIlosc++;
}
MyClass(int a1, int c1) // parametrized constructor
{
_a=a1;
c = new int [c1];
for(int i = 0; i<=c1; i++)
{
c[i] = rand();
}
fIlosc++;
}
MyClass(const MyClass &p2) // copy constructor
{
_a =p2._a;
c = p2.c;
fRozmiar = p2.fRozmiar;
fIlosc = fIlosc;
fIlosc++;
}
~MyClass(); // destructor
static int getCount() {
return fIlosc;
}
};
//Initialize static member of class
int MyClass::fIlosc = 0;
MyClass::~MyClass()
{
for(int i = 0; i<sizeof(c); ++i)
{
delete[] c[i];
}
delete[] c;
fIlosc--;
}
int main()
{
}
Remove the for-loop, but keep the delete[] c after it.
Each int doesn't need to be deleted because they're not dynamically allocated. If you needed to delete them, then the for-loop wouldn't work becuase: sizeof(c) is not the size of the array, and delete[] should have been delete instead.
There are several problems in the code.
First, that loop in the destructor must go. If you didn’t new it, don’t delete it.
Second, a loop through an array of N elements should be for (int i = 0; i < N; ++i). Note that the test is i < N, not i <= N. The loops as currently written go off the end of the array. That’s not good.
Third, the copy constructor copies the pointer. When the first object goes out of scope its destructor deletes the array; when the copy goes out of scope its destructor also deletes the array. Again, not good. The copy constructor has to make a copy of the array. In order to do that the class needs to also store the number of elements the array.

Constructor Initialization and private variables set inside constructor

My constructor is suppose to only take one variable. But I'm curious if you ca initialize other variables that arent in the constructor defintion.
class WordAnalysis{
private:
int timesDoubled;
word *words;
int wordCount;
int index;
void doubleArrayAndAdd(string);
bool checkIfCommonWord(string);
void sortData();
public:
bool readDataFile(char*); //returns an error if file not opened
int getWordCount();
int getUniqueWordCount();
int getArrayDoubling();
void printCommonWords(int);
void printResult(int);
WordAnalysis(int);
~WordAnalysis();
};
Example: Would any instance of WordAnalysis now have timesdoubled as 0. and would a getter function be able to get this information without a setter?
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
Well yes, you can initialize other member variables in the constructor,
even if it doesn't take the corresponding arguments.
However, in the example you gave above:
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
You aren't actually initializing the timesDoubled member variables, because you wrote "int" before it, which is declaring a new variable and setting that to 0.
If you want to set the classes timesDoubled variable you have to write:
timesDoubled = 0;
Or if you want to be more explicit about it, you can even write:
WordAnalysis::timesDoubled = 0;
Yes. You can. But, you can do in-class initialization of your data members on declaration. You should use initializer list with constructor to initialize your required data members. All the data members are visible inside the constructor. You can assign their values in it. Technically, using initializer list is initialization and inside the ctor it is assignment when the assignment operator (=) is used.
Here's is the snippet of your code with comments:
class WordAnalysis
{
private:
// Data member initialization on declaration
int timesDoubled { 0 };
word* words { nullptr };
int wordCount { 0 };
int index { 0 };
public:
// Initializing timesDoubled using initializer list
WordAnalysis( const int t ) : timesDoubled{ t }
{
// Assign default values here if need be
index = 10; // assignment
}
// ...
};
Your compiler should be at least C++11 compliant to allow the in-class initializations of data members.
I suggest defining a default constructor such as:
WordAnalysis()
{
timesDoubled = 0;
words[0] = '\0'; //assuming it's an array of char
wordCount = 0;
index = 0;
}
That way all instances of the class would be initialized.

Understanding this code involving pointers, arrays, and the new operator

So this is the original code:
class IntegerArray {
public:
int *data;
int size;
};
int main() {
IntegerArray arr;
arr.size = 2;
arr.data = new int[arr.size];
arr.data[0] = 4; arr.data[1] = 5;
delete[] a.data;
}
After moving arr.data = new int[arr.size] to a constructor, it becomes
class IntegerArray {
public:
int *data;
int size;
IntegerArray(int size) {
data = new int[size];
this->size = size;
}
};
int main() {
IntegerArray arr(2);
arr.data[0] = 4; arr.data[1] = 5;
delete[] arr.data;
}
I'm fairly lost on what the code is trying to do. For
IntegerArray(int size) {
data = new int[size];
this->size = size;
}
Is int size just the same as the int size that was declared in the class IntegerArray?
Does data = new int[size] just tell us that data is pointing to the output of the array at int size, with new saying that the size of the array is variable?
Is this-> size = size just a pointer that tells us that the size value of the constructor is just equal to the size parameter of the class?
Why are arr.data[0] and arr.data[1] even mentioned after IntegerArray arr(2)? They don't seem to follow the constructor, but I'm probably just too tired to comprehend that part.
IntegerArray(int size) {
data = new int[size];
this->size = size;
}
Is int size just the same as ...
This int size:
IntegerArray(int size) {
^^^^^^^^
is an argument to the constructor
Does data = new int[size] just tell us ...
new int[size] dynamically allocates an array that contains size number of int objects. data pointer is then assigned to point to that newly created array.
Is this-> size = size just a pointer ...
No. this is a special pointer, that within the constructor points to the object that is being constructed. this->size is the member variable that was declared here:
class IntegerArray {
public:
int *data;
int size;
^^^^^^^^
The complete expression this->size = size assigns the value size that is the constructor argument, to the member variable size.
Why are arr.data[0] and arr.data[1] even mentioned after IntegerArray arr(2)?
The constructor does not initialize the contents of the array (the integer objects within the array). The mentioned code does assigns a values to them.
this->size = size //the fist size is your member variable which is inside IntegerArray. the 2nd size is the size you give over to the Method
data = new int[size]; // here you are creating a new array with the size of "size"
the method IntegerArray(int size) is a constructor method, you only can call it once per object (even at the time when you create the object)
int main() //the startpoint of your program
{
IntegerArray arr(2); //you are creating a new object with a size of 2
arr.data[0] = 4; arr.data[1] = 5; //because of your array is public, you can call it direct from outside (you sould define it as private ore protected). arr.data[0] is the first item of the array, arr.data[1] is the 2nd item
delete[] arr.data;
}
delete[] arr.data; should be inside the destructor of your class...

Using a class' constructor within a vector of the same type in C++

Consider:
MyClass {
//constructor
MyClass()
{}
.
.
.
};
Then, defining a vector of the same type
int main()
{
.
.
vector<MyClass>myVector(12);
.
.
Is this allowed?
for(int i = 0; i < myVector.size(); i++)
{
//an attempt to fill my vector with initialized MyClass objects.
myVector[i] = MyClass(); //Calling constructor
}
OR:
(in the case of not defining a vector's size)
for(int i = 0; i < whatever; i++)
{
//an attempt to fill my vector with initialized MyClass objects.
myVector.push_back(MyClass()); //Calling constructor
}
If this is not allowed, what is an alternative for initializing class instances and storing them in a vector without using pointers? Is there such a thing?
Everything you wrote is acceptable.
vector<MyClass>myVector(12);
will call default constructor of MyClass 12 times. So this is equivalent to
vector<MyClass>myVector;
for(int i = 0; i < 12; i++)
{
myVector.push_back(MyClass());
}
Another variant you provided is slightly different
for(int i = 0; i < myVector.size(); i++)
{
myVector[i] = MyClass();
}
Here every element of vector is already initialized somehow. So when you do this, previous instance of MyClass will be removed (destructor will be called) and element will be assigned to new instance.
If you need make your default constructor private and initialize class with some value you have to use next aproach:
vector<MyClass>myVector(12, MyClass(some_value));
or as you already seen
vector<MyClass>myVector;
for(int i = 0; i < 12; i++)
{
myVector.push_back(MyClass(some_value));
}

Construct object, where one of its properties depends on another. In C++

Beginner in C++
I have a class, say
class A
{
public:
int N;
double .....
};
But I would like the ..... to define a matrix of size depending on N. In case that changes the approach, it is a non-identical function of N and not just N itself, say N^3+1.
In case that is the approach, I have never written a constructor of an object in C++. Therefore, if this is the approach could you please give some detail. I don't understand how it might work. When the class is instanciated, maybe the property N hasn't been even initialized.
I am not clear how to get a matrix or array (I am still not clear of the basic data types of C++) of size determined in execution.
Edit: The value of N is determined later in the code. It is something like:
A InstanceOfA; //The variable InstanceOfA is declared of type A.
...
Some other stuff happens, e.g. other properties of InstanceOfA are initialized
and some of the functions are used. And then:
...
A.setN(4);
I didn't understand from the answer below. Would I need to do
A InstanceOfA(4);
?
You can use std::vector
class A
{
public:
int N; // you should use int for size
double std::vector<std::vector<double>> matrix; //define the matrix
//initialize it in the constructor
A( int size ):N(size), matrix(size*3+3)// or you can use any expression that evaluates an integral value
{
//you can initialize the values in matrix here
}
};
Note
the expression matrix(size*3+3) initializes the matrix such that, there are size*3+3 rows, the number of columns in each row are not specified yet. You can also specify column sizes in the constructor like
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
Edit
As per the modification in question, you can then leave the constructor empty (or initialize any other members), and provide a setSize method in class A, which will later initialize the size.
void setSize(int size){
N= size;
matrix.resize( size*3+3);
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
}
Then you can use it like:
A instanceOfA;
//other code
//
instanceOfA.setSize(N);
You can use an std::vector<std::vector<double>> to capture the matrix. Also, change the type of N to int.
class A
{
public:
int N;
std::vector<std::vector<double>> matrix;
};
Define a constructor and initialize the data in the constructor.
class A
{
public:
A(int n) : N(n)
{
int matrixSize = N*N*N+1;
for (int i = 0; i < matrixSize; ++i )
{
matrix.push_back(std::vecotr<double>(matrixSize));
}
}
double N;
std::vector<std::vector<double>> matrix;
};
One possible way is to do it with a pointer. If you only allocate your array in constructor and its size will not change during the lifetime of your object, that could be done in this way:
class A
{
public:
double N;
double* arr;
A(double aN):N(aN)
{ arr = new double[3*N+1]; // allocate your array in constructor
... // do whatever else you need to initialize your object
}
...
~A() { delete[] arr;} // free it in destructor
...
}
See also the tutorial on Dynamic Memory.
You will then instantiate your class in one of two ways:
A a(aN);
// this object will be automatically destroyed when it gets out of scope, for example at the end of the function where it was created
A* a = new A(aN);
// this object will have to be deleted by yourself when it's no longer needed:
...
delete a;
If you don't know N at the moment when you create your object, you can postpone the allocation :
class A
{
public:
double N;
double* arr = NULL;
A() { ... } // do whatever you need in your constructor
setN(double aN)
{
N = aN;
arr = new double[3*N+1]; // allocate your array
}
...
~A() { if(arr) delete[] arr;} // free your array in destructor if needed
...
}
then you can call your object as:
A a;