Pointer to a class with array indexing operator overload - c++

I have a class which has overloaded the array index operator[]. Now I have to create a pointer to that class, How can I use index operator [] using pointer to the class. Following code works fine, but if i un-comment the basicVector * a = new basicVector(10) line and put -> in place of ., I get errors.
Please see this link for compiler settings and code.
#include <iostream> // std::cout
#include <queue> // std::queue
#include <string>
#include <string.h>
#include <stdint.h>
#include <vector>
using namespace std;
class basicVector
{
private:
uint32_t array_size;
uint8_t * array;
public:
basicVector(uint32_t n);
~basicVector();
uint32_t size();
uint8_t * front();
uint8_t& operator[](uint32_t i);
};
basicVector::basicVector(uint32_t n)
{
array_size = n;
array = new uint8_t[n];
}
basicVector::~basicVector()
{
delete [] array;
}
uint32_t basicVector::size()
{
return array_size;
}
uint8_t * basicVector::front()
{
return array;
}
uint8_t& basicVector::operator[](uint32_t i)
{
return array[i];
}
int main ()
{ //basicVector * a = new basicVector(10);
basicVector a(10);
cout <<a.size()<<endl;
for(uint8_t i=0; i < a.size(); i++)
{ a[i] = i+50; //how to do this correctly when "a" is pointer?
}
uint8_t * b = &a[3]; //how to do this correctly when "a" is pointer?
*b = 45;
for(uint32_t i=0; i < a.size(); i++)
{ cout<<a[i]<<endl; //how to do this correctly when "a" is pointer?
}
return 0;
}

With the following declaration:
basicVector *a = new basicVector(10);
You could dereference the pointer (preferred):
uint8_t n = (*a)[5];
Or call the operator using the operator syntax:
uint8_t n = a->operator[](5);

Related

I cant seem to assign a pointer an array and then change the contents of the array

I couldn't figure out how to make a function return an array so instead I decided to try and pass an empty array (of the correct size) into my function and than reassign the address to a different array of the same size. Is this at all a way to do things??? Can someone show me what to do? if this is wrong can you fill me in on how to do this?
here is my code:
#include <iostream>
#include <cmath>
using namespace std;
void ArrayFiller(int earray,int s, int f){
int *ptrarray = &earray;
int prenum_size = std::abs(s) + f - 1;
int pre_num[prenum_size];
for(int x=s;x<f;x++){
pre_num[x+std::abs(s)] = x;
}
*ptrarray = pre_num;
}
int Main(){
int first = -10;
int second = 15;
int temp[abs(first) + abs(second)];
ArrayFiller(temp, first, second);
int n = sizeof(temp)/sizeof(temp[0]);
for (int i = 0; i < n; i++) {
cout << temp[i] << ' ';
}
return 0;
}
I think you're looking for something like this:
#include <iostream>
#include <cmath>
using namespace std;
void ArrayFiller(int earray[],int s, int f){
for(int x=s;x<f;x++){
earray[x+(std::abs(s))] = x;
}
}
int main(){
int first = -10;
int second = 15;
int n = abs(first)+abs(second);
int* temp = new int[n];
ArrayFiller(temp, first, second);
for (int i = 0; i < n; i++) {
cout << temp[i] << ' ';
}
delete [] temp;
return 0;
}

Getting the same string (gene array) in every object in the array dna (dynamically allocated)

I have created a class called DNA, having a no argument constructor and two member functions namely initialize() and show(). The problem is when I create an
array using new operator and call the initialize function on every object using a for loop, instead of getting different string in the member variable "genes", I am getting the exactly the same set of characters (array) in the genes in every object in the array. Although I seed the srand() function before initialization of the string, there is no effect seen of it.
The code below.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA {
private:
int length;
char *genes;
public:
DNA() {
length = 0;
genes = new char[length];
}
void initialize(int len) {
srand(unsigned(time(NULL)));
this -> length = len;
delete genes;
this -> genes = new char[length];
for (int i = 0; i < length; i++) {
*(genes + i) = sampleSpace.at(rand() % sampleSpace.length());
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<*(genes + i);
}
cout<<endl;
}
};
int main() {
DNA *dna = new DNA[10];
DNA *temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).initialize(10);
temp++;
}
temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).show();
temp++;
}
return 0;
}
You should use the new random API and use a proper random engine:
class DNA {
private:
int length;
std::unique_ptr<char[]> genes;
static std::default_random_engine random;
public:
DNA() : length{0}, genes{} {}
void initialize(int len) {
this-> length = len;
this-> genes = std::make_unique<char[]>(length);
std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.size() - 1};
for (int i = 0; i < length; i++) {
genes[i] = sampleSpace.at(distribution(random));
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<genes[i];
}
cout<<endl;
}
};
This will initialize a std::default_random_engine and use a proper number distribution. Also, I changed the code for unique pointer.
Here's a live example.
To piggyback on the answer given, here is the equivalent answer, but using std::vector and std::generate:
#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>
#include <random>
std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA
{
private:
std::vector<char> genes;
public:
void initialize(int len)
{
static std::default_random_engine random;
genes.resize(len);
std::uniform_int_distribution<size_t> distribution{0, sampleSpace.length()-1};
sampleSpace.at(distribution(random));
std::generate(genes.begin(), genes.end(), [&] ()
{ return sampleSpace.at(distribution(random)); });
}
void show()
{
for (auto& v : genes)
std::cout << v;
std::cout << "\n";
}
};
int main()
{
DNA dna[10];
for (int i = 0; i < 10; i++)
dna[i].initialize(10);
for (int i = 0; i < 10; i++)
dna[i].show();
}
Live Example
Note that length is also no longer needed.

Why is move constructor used over copy constructor?

This is simple program that is supposed to handle a dynamic array of numbers and then to filter out the elements that are even and put them into a new array and then print both arrays on the screen.
This is the header file:
#pragma once
namespace filter
{
class Array
{
double *arr;
int n;
public:
Array();
Array(int);
Array(const Array&);
Array(Array&&);
void PutIn();
void PrintOut() const;
Array isEven();
Array filter(const std::function<bool(int)>&) const;
~Array();
};
}
Then, this is the implementation of functions:
#include <iostream>
#include <functional>
#include "Array.h";
using namespace filter;
using namespace std;
Array::Array() :arr(nullptr), n(0)
{ }
Array::Array(int n)
{
this->n = n;
arr = new double[n];
}
Array::Array(const Array &a1)
{
n = a1.n;
arr = new double[n];
for (int i = 0; i < n; i++)
arr[i] = a1.arr[i];
}
Array::Array(Array &&a1)
{
n = a1.n;
for (int i = 0; i < n; i++)
arr[i] = a1.arr[i];
a1.n = 0;
a1.arr = nullptr;
}
void Array::PutIn()
{
cout << "Insert elements:\n";
for (int i = 0; i < n; i++)
cin >> arr[i];
}
void Array::PrintOut() const
{
cout << "\nYour array is :\n";
for (int i = 0; i < n; i++)
cout << arr[i] << "\t";
}
Array Array::isEven()
{
return filter([](int x) { return x % 2; });
}
Array Array::filter(const std::function<bool(int)> &f) const
{
int b = 0;
for (int i = 0; i < n; i++)
if (f(arr[i]) == 0)
b++;
Array temp(b);
b = 0;
for (int i = 0; i < n; i++)
if (f(arr[i]) == 0)
{
temp.arr[b] = arr[i];
b++;
}
return temp;
}
Array::~Array()
{
delete[]arr;
n = 0;
}
Finally, this is the source code:
#include <iostream>
#include <functional>
#include "Array.h"
using namespace filter;
using namespace std;
int main()
{
Array a(5);
a.PutIn();
Array b = a.isEven(); //WHY THIS LINE OF CODE INVOKES MOVE CONSTRUCTOR AND NOT COPY CONSTRUCTOR?
a.PrintOut();
b.PrintOut();
getchar();
getchar();
}
So, as you can see, this is relatively simple program that needs to handle an array with five elements in it entered by user and then to create a new array that consists of even elements of the first array. When i run this, it works fine, however, there is one little thing that i don't understand here.
If you look at the source code, notice the line where i left my comment, that is the line where move constructor is called, but i don't know why. That would mean that a.IsEven() is a RVALUE, since move constructor works with RVALUES, right? Can anyone explain me why this is rvalue and what is the correct way to understand this? Any help appreciated!
Your assumption that calling isEven invokes your move constructor is not in fact correct. Nor does it invoke your copy constructor. Instead, RVO ensures that the object returned is constructed directly at the calling site so neither is required.
Live Demo (which doesn't address any of the flaws in your code mentioned in the comments).

What's wrong on passing this double pointer and get the value?

I'm new/noob programmer of C++, and I've this problem. I want to pass a pointer of double to a function (which will process some data on it) and read (after the process) a fixed value of that "array". I've do this:
void ReadDoubles(double* samples, int size)
{
for (int i=0; i < size; ++i)
{
*samples = i*10.1;
samples++;
}
}
int main()
{
int size = 10;
double *values=0;
ReadDoubles(values, size);
cout << *(values+3);
}
BUt of course it seems I can't init the pointer that way. I think I need to init the pointer allocating 10 values? Tried:
double *values[size];
but that's not the solution. How would you do this simple task?
You need to allocate the array at first. Here you are
#include <iostream>
void ReadDoubles( double* samples, size_t size )
{
for ( size_t i = 0; i < size; ++i )
{
*samples = i*10.1;
samples++;
}
}
int main()
{
size_t size = 10;
double *values = new double[size];
// ^^^^^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
delete []values;
}
The program output is
30.3
If you don't want to use the operator new then there are two general approaches. Either you can declare an array as for example
int main()
{
const size_t size = 10;
//^^^^
double values[size];
// ^^^^^^^^^^^^
ReadDoubles( values, size );
std::cout << *(values+3) << std::endl;
}
or you can use standard class std::vector<double>.In this case the function should be rewritten appropriately.
For example
#include <iostream>
#include <vector>
void ReadDoubles( std::vector<double> &samples, size_t size )
{
samples.resize( size );
for ( size_t i = 0; i < size; ++i )
{
samples[i] = i*10.1;
}
}
int main()
{
size_t size = 10;
std::vector<double> values;
ReadDoubles( values, size );
std::cout << values[3] << std::endl;
}
If you are not allowed to change the RealDoubles function and you must have a function return the size then the following should work:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
double *values = new double[size] {0}; // Use new to allocate array. Optional: use {0} to init first element to 0, others default initialized to 0
ReadDoubles(values,size);
cout << *(values+3);
delete[] values;
}
If you prefer to avoid new and delete then you can let a std::vector manage the container for you:
#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <vector>
using namespace std;
void ReadDoubles(double* samples,int size)
{
for (int i=0; i < size; ++i) {
*samples = i*10.1;
samples++;
}
}
int get_size()
{
return 10;
}
int main()
{
int size = get_size(); // get size from function
//double *values=0;
std::vector<double> value_container(size,0); // vector will do the new and delete for us
double *values = value_container.data();
ReadDoubles(values,size);
cout << *(values+3);
} // vector destructor will do delete when it goes out of scope

Program keeps getting segmentation fault

Coding this in CodeBlocks, this program keeps getting a seg fault. Could anyone help?
#include <string>
#include <iostream>
#include <sstream>
#include "include/hugeint.h"
using namespace std;
int main(int argc, char *argv[])
{
HugeInt h("123");
return 0;
}
my HugeInt Class (whats relevant), stores very large integers as an array of integers
class HugeInt
{
public:
HugeInt(string);
private:
DynArray dyn;
//HugeInt& reverse();
int size;
};
HugeInt::HugeInt(string input)
{
string digits = input;
for(unsigned int i = 0; i < digits.length(); i++){
dyn.add(digits.at(i) - 48);
}
size = dyn.size();
}
my dynamic array class of integers
class DynArray
{
public:
DynArray();
~DynArray();
private:
int length;
int *arr; //points to this array
int nextIndex;
};
DynArray::DynArray() {
arr = new int[10];
for (int i = 0; i < 10; i++)
arr[i] = 0;
length = 10;
nextIndex = 0; }
DynArray::~DynArray()
{
delete [] arr;
}
int DynArray::size(){
return nextIndex;
}
void DynArray::add(int val) {
int *newArr;
if (nextIndex == length) {
length = length + 10;
newArr = new int[length];
for (int i = 0; i < nextIndex; i++)
newArr[i] = arr[i];
for (int j = nextIndex; j < length; j++)
newArr[j] = 0;
delete [] arr;
arr = newArr;
}
arr[nextIndex++] = val;
}
Edit: I commented delete [] arr; out and it still seg faults :/
Edit2: OK so the code works if main is as follows. Can Anyone explain why please?
#include <string>
#include <iostream>
#include <sstream>
#include "include/hugeint.h"
using namespace std;
int main(int argc, char *argv[])
{
string in = "1234";
HugeInt h(in);
return 0;
}
You may need to initialize the DynArray in the HugeInt constructor before you start using the DynArray add() method. You didn't include the add method in the code but if it does what I imagine it does, you may have not constructed the DynArray object before using it, thus the seg fault.
The code you've posted compiles and runs without error.
I can speculate that problems are happening elsewhere because DynArray does not satisfy the rule of three.
Currently, if a DynArray is copied in any way, that copy will hold the same pointer to the same int *arr.
And when that copy is destroyed, so is the array used by all the other copies.