C++ Dynamic Constructor - c++

I'm getting the error:
no operator "[]" matches these operands
For the line:
cout << A[j].display(n)
But when I take out the [j], I'm getting the error:
class "list" has no member "display"
Here is my code:
class list
{
protected:
int *p; // pointer to a list
int size; // dimension
public:
list(int x)
{
size = x;
p = new int[size];
}
void get(int i, int val)
{
p[i] = val;
}
};
class dlist : public list
{
public:
int display(int i)
{
return p[i];
}
};
int main()
{
int n;
cout << "Enter elements in a row\n";
cin >> n;
list A(n);
int j, val;
for (j = 0; j < n; j++)
{
cin >> val;
A.get(j, val);
}
cout << "\n";
cout << "List of elements are :\n";
cout << "----------------------\n";
for (j = 0; j < n; j++)
cout << A[j].display(j) << "\t";
cout << "\n";
return 0;
}
Please help!

The class list indeed has no member function display. It is the class dlist declared like
class dlist : public list
//...
has such a member function. However the object A was defined in main like an object of class list
list A(n);
Moreover you can not create an object of the type dlist because you have to define explicitly a constructor of the type.
If you want to use polymorphism then introduce virtual functions making for example the member function display like virtual.
Also this syntax
cout << A[j].display(j) << "\t";
^^^^^^^^^^^^^^
is incorrect because the object A is a scalar object. It is not an array of objects and the class has no overloaded operator [].
You should start by defining explicitly a virtual destructor (otherwise there can be a memory leak in your program) that delete dynamically allocated memory in the constructor with parameter, copy constructor and the copy assignment operator in the class list. Then you can define the subscript operator and so on.

Related

Calling a Function in a Class with Parameters C++

I'm practicing in order to better understand dynamic arrays and using them in a class. However, I'm struggling to call my functions inside the class. I have no issue with my int size variable, but my int myArray variable is giving me problems. I get the error "expected a member name" when I try to call my void functions in my main function. Are arrays not allowed to be used in this situation?
#include <iostream>
using namespace std;
class myClass
{
public:
int size;
int* myArray = new int[size];
void storeData(int& size, int (&myArray)[]);
void printData(int& size, int(&myArray)[]);
};
void myClass::storeData(int& size, int(&myArray)[])
// Stores array data.
{
cout << "Enter Size of the array: ";
cin >> size;
// User determines array size.
for (int x = 0; x < size; x++)
{
cout << "Array[" << x << "]: ";
cin >> myArray[x];
// User determines array values.
cout << endl;
}
}
void myClass::printData(int &size, int(&myArray)[])
// Displays values of the array.
{
cout << "Value of the arrays are: ";
for (int x = 0; x < size; x++)
{
cout << myArray[x] << " ";;
}
delete[]myArray;
}
int main()
{
myClass object;
object.storeData(object.size, object.(&myArray)[]);
// E0133 expected a member name.
object.printData(object.size, object.(&myArray)[]);
// E0133 expected a member name.
}
There are a couple issues here, I will try to address all of them.
When passing an array to a function, never use [] syntax. In C and C++, arrays decay to pointers, so we do not need [] nor &.
This is valid syntax to pass an array:
int my_array [] = {1,2,3,4};
my_function(my_array, 4);
...
void my_function(int * array, size_t size)
{
//Iterate over the array or do something...
}
In addition, if a function exists within a class, it can access class members freely, meaning we do not have to pass them in at all. See the following change to your code:
void myClass::storeData(int size)
// Stores array data. We do NOT need a pointer to the object array, we already have it!
{
cout << "Enter Size of the array: ";
cin >> size;
// User determines array size.
for (int x = 0; x < size; x++)
{
cout << "Array[" << x << "]: ";
cin >> myArray[x];
// User determines array values.
cout << endl;
}
}
Lastly, dynamic sized arrays must be allocated dynamically. Do not use int* myArray = new int[size]; in your class definition, because size is not yet initialized. Instead, use a constructor or use your store_data function to allocate the memory.
class myClass
{
public:
size_t size;
int * myArray; //Do not allocate anything here...
myClass(size_t size)
{
this->size = size;
myArray = new int[size];
}
};
You can get the size however you want, via user input, etc. and pass this to the constructor or an allocator function like storeData.

how to copy Int array to int pointer using constructor in C++

I am trying to insert int array x to int *v. here is my code . please provide me with optimal solutions and the reason behind it.
there is an error in this line. Instead of copying array value its taking garbage value. line v1=x;
class vector
{
int *v;
int size;
public:
vector(int m)
{
v = new int[size = m];
for (int i = 0; i < size; i++)
v[i] = 0;
}
vector(int *a)
{
for (int i = 0; i < size; i++)
v[i] = a[i];
}
int operator *(vector &y)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += v[i] * y.v[i];
return sum;
}
void disp()
{
for (int i = 0; i < size; i++)
cout << v[i] << " ";
cout << "\n";
}
};
int main()
{
clrscr();
int x[3] = { 1,2,3 };
int y[3] = { 4,5,6 };
vector v1(3);
//v1.disp();
vector v2(3);
v2.disp();
v1 = x;
v1.disp();
//v2=y;
v2.disp();
int r = v1 * v2;
cout << "R = " << r;
getch();
return 0;
}
You forgot to add the assignment operator in your vector class:
vector & operator=(int *a)
{
for (int i = 0; i < size; i++)
v[i] = a[i];
return *this;
}
In the the line
v1=x;
May be, you are expecting it to invoke the second constructor which takes int* as argument. But it won't happen.
It can be seen as Type Conversion from Basic type to Class type. where we expect appropriate constructor will get invoked.
see http://www.hexainclude.com/basic-to-class-type-conversion/
But remember, Constructor will be invoked only once after the creation of object.
Here, in the line
vector v1(3);
the first constructor was already invoked. Then the line
v1=x;
won't invoke the second constructor now.
For every class, = operator is default overloaded . That is the reason why we can easily assign objects to one another.
Therefore, the line v1=x invokes default overloaded assignment = operator.
Here, it treats address of array x i.e., &x[0] as address of class object. As it is not address of vector class object
=> it results a Segmentation fault.
YOUR ANSWER
To assign int array to int pointer i.e., to the member variable int* v of the vector class,
overload assignment operator = inside the class .
or
Initialize the class object to array in first line itself. i.e.,
vector v1=x; // modify the class constructor to have size as a constant.

identifier "fill_vector" is undefinded and im not sure why

int miniVector<T>::fill_vector(miniVector<T> &obj)
{
int numofelements;
cout << "For how many objects do you want to enter value<s>? ";
cin >> numofelements;
obj.resize(numofelements);
int i;
for(i = 0; i < numofelements; i++)
{
cin >> obj[i];
obj.push_back(i);
}
return i;
}
int main()
{
miniVector<int> v;
cout << "int vector: " << endl;
//fill_vector();
int sizearray;
sizearray = fill_vector<int>(v);
sizearray = v.size();
//display_vector(v, sizearray);
return 0;
}
Was wonder why i keep getting an error message idnetifier "fill_vector is undefined.
int miniVector<T>::fill_vector(miniVector<T> &obj)
This says: a method of a class miniVector of type T, that returns an int and takes in a reference to a miniVector object of type T.
You cannot call this as you have, using
sizearray = fill_vector<int>(v);
You would have to call it like this:
sizearray = v.fill_vector(some_other_miniVector);
where
some_other_miniVector is
miniVector<int> some_other_miniVector;
fill_vector is a member function of class miniVector. Thus you have to specify an object for which the member function is called in this statement (if the member function is non-static) or class name (if the member function is static)
sizearray = fill_vector<int>(v);
This call is wrong also because the method itself is not template.
So there is no definition of template function fill_vector and the compiler issues an error.

second Constructor called in c++ ( wrong output)

I am trying to do a simple thing but suddenly stuck in between .
Here in my code I am trying to call a constructor in which i would only pass the length, my first constructor initializes an array of size = length with all elements 0.
Then i am passing the array to the constructor to give the previously defined array its values
here is the sample :
class myvector
{
int *arr;
int length;
public :
myvector(int);
myvector(int *);
};
myvector :: myvector (int len)
{
arr = new int [length = len];
for ( int i=0;i< length;i++)
{
arr[i] = 0;
}
}
myvector :: myvector ( int *ex)
{
for ( int i=0;i< length;i++)
{
cout << ex[i] << " " << length <<" ";
arr[i] = ex[i];
cout << arr[i]<< " ";
}
}
int main()
{
myvector v1(5);
int x[5] = {2,3,4,45,6};
v1 = x;
}
Here in my second constructor length which was defined in first constrcutor lost its values , also array arr loses its values
Did I do something ?
Please elaborate me on this
I don't think you quite get what the circumstances are in which constructors are invoked. The line v1 = x doesn't put the values into the memory allocated during the first constructor call. Rather, it constructs a new myvector (using the second constructor) and copies it into v1. The stuff you do during the first constructor call is lost.
It sounds like you want to define an assignment operator, not a constructor taking an int* argument. Also, in general you should declare single-argument constructors as explicit to prevent this sort of thing from happening accidentally.
First of all, when specifying a size of array like this, you should provide a constant value. See here. And I really encourage you to use std::vector<> for such tasks.
But anyway, like Sneftel mentioned, seems like you want to define an assignment operator (see here for more information about overloading operators in tasks like yours).
Here how I'd implemented it(NOT and ideal solution, but it works, and gives a basic idea):
#include <iostream>
using namespace std;
class myvector
{
int *arr;
int length;
public :
//I completely removed second constructor
myvector(int);
~myvector();
void operator=(const int* otherArray);
void printArray();
};
myvector::myvector (int len)
{
length = len;
arr = new int[length]; // This is the way, how you can handle a non constant array sizes
for ( int i=0;i< length;i++)
{
arr[i] = 0;
}
}
void myvector::printArray()
{
for(unsigned i = 0; i < length; ++i)
cout<<"arr["<<i<<"] = "<<arr[i]<<endl;
}
//Here's an overloaded '=' operator.
//int x[5] = {2,3,4,45,6};
//myvector v;
//v = x; - here this function is called
void myvector::operator=(const int* otherArray)
{
for(unsigned i = 0; i < length; ++i)
arr[i] = otherArray[i];
}
myvector::~myvector()
{
delete []arr; // You should ALWAYS delete what you allocated with new
}
int main()
{
myvector v1(5);
int x[5] = {2,3,4,45,6};
v1 = x;
v1.printArray();
}

operator overloading in c++ - A query

I was reading a book on operator overloading in c++ and I encountered the following code:
class Array {
...
public:
Array & operator << ( int x) {
// insert x at the end of the array
}
};
Next It says: that overloading of the form a << x << y << z ;
wll not workSo It suggests that second invocation is treated as :( (a << x)<< y ) << z .so it recommends using return *this;
But I am not getting how return *this functions here? Please help!Here is the entire code:
#include <iostream>
#include <cstdlib>
using namespace std;
class Array {
int *a;
int capacity;
int size;
int incr;
public:
Array (int c=10) {
a = new int[c];
capacity = c;
for (int i=0; i<c; i++) a[i]=0;
size=0;
incr = c;
}
Array &operator << (int x) {
if(size<capacity) a[size++] = x;
else {
int *tmp = new int [capacity+incr];
for (int i=0; i<size; i++) tmp[i]=a[i];
delete[] a;
a = tmp;
a[size++]=x;
capacity = capacity+incr;
}
return *this;
};
int operator [] (int i) {
if(i<size) return a[i];
};
};
int main (int argc, char *argv[]) {
int s = atoi (argv[1]);
Array A (s);
for (int i=0; i<s; i++) A << i << i+1;
for (int i=0; i<s; i++) cout << A[i] << endl;
}
This really has nothing to do with operator overloading. It's called chaining and it's easier to explain using regular member functions. Suppose you defined a member function called insert like this:
Array& insert(int x) {
// insert x at the end of the array
return *this;
}
The return *this will return a reference to the current object so that you can chain calls like this:
Array a;
a.insert(0).insert(1).insert(2);
Which is essentially equivalent to:
Array a;
a.insert(0);
a.insert(1);
a.insert(2);
Each call to insert() will return a reference to the original object, allowing other calls to be made using that returned reference. You can overload the << operator to do the same thing:
Array& operator<<(int x) {
// insert x at the end of the array
return *this;
}
Now you can chain calls like this:
Array a;
a << 0 << 1 << 2;
You may be getting confused because of the spacing of Array &operator <<. The return value of the function is Array&, a reference to the array object.
Here's an example. In your call A << i << i+1, the A << i is called first and a reference to the updated A is returned. Next A << i+1 is called, with that new reference.
Yes everything is ok with your code. operator << in your semantics will and returning refference to same object which called it. You can see same in code of operator << of std::ostream and operator >> of std::istream.