Private function for operator overload - c++

I am learning about operator overloading in C++. To try it out, I overloaded the [] operator to print the value at the index given. The code worked when I defined the operator overload member function as public.
However when I tried to do the same thing by defining the overload method as private, the code does not work. It does not even enter the operator overload method and skips it completely.
Can somebody please explain to me what am I doing wrong? Do operator overload methods have to be public only?
Here is my code:-
#pragma once
class NArray
{
public:
NArray(int size=100);
int getValueAt(int index);
~NArray();
void test(int index);
//int operator[](int index) const;
private:
int sizeOfArray;
int array[100];
int operator[](int index) const;
};
#include "NArray.h"
#include <iostream>
using namespace std;
NArray::NArray(int size)
{
if (size > 0 && size <=100)
sizeOfArray = size;
else
sizeOfArray = 100;
for (int i = 0; i < sizeOfArray; i++)
{
array[i] = i;
}
}
int NArray::getValueAt(int index)
{
if (index > 0 && index <sizeOfArray)
{
return array[index];
}
else
{
return -1;
}
}
int NArray::operator[](int index)const
{
if (index > sizeOfArray || index < 0)
{
cout << "Index out of bounds" << endl;
return -1;
}
else
{
cout << array[index] << endl;
return array[index];
}
}
void NArray::test(int index)
{
array[index];
}
NArray::~NArray()
{
}
#include <iostream>
#include "NArray.h"
using namespace std;
int main()
{
int size = 0;
int index = 0;
cout << "Enter Array Size:" << endl;
cin >> size;
NArray arr(size);
cout << "Enter Index:" << endl;
cin >> index;
//This works for the public operator method
//arr[index];
//This does not
arr.test(index);
getchar();
return 0;
}
Thanks in advance.

test is not using NArray::operator [], it is accessing array directly. Try changing array[index]; to (*this)[index]; inside of NArray::test, and make it const while you're at it since it's not modifying anything:
void test(int index) const;
// ...
void NArray::test(int index) const
{
(*this)[index];
}
Also, you have a bug in operator[] – if (index > sizeOfArray || index < 0) should be if (index >= sizeOfArray || index < 0).

Related

'this' cannot be used in a constant expression error

The error is on line 76 int res[mSize]; the problem is on mSize. It seems like a simple fix but I can't figure it out. If someone can figure it out or point me in the right direction that would be greatly appreciated.
Also, the deconstructor ~MyContainer(), I am not sure if I am using it right or if there is a correct place to put it.
Here is my code:
#include <iostream>
using namespace std;
class MyContainer
{
private:
int* mHead; // head of the member array
int mSize; // size of the member array
public:
MyContainer();
MyContainer(int*, int);
//~MyContainer();
void Add(int);
void Delete(int);
int GetSize();
void DisplayAll();
int FindMissing();
~MyContainer() {}
};
MyContainer::MyContainer()
{
mHead = NULL;
mSize = 0;
}
MyContainer::MyContainer(int* a, int b)
{
mHead = a;
mSize = b;
}
void MyContainer::Add(int a)
{
*(mHead + mSize) = a;
mSize++;
}
void MyContainer::Delete(int a)
{
int index;
for (int i = 0; i < mSize; i++)
{
if (*(mHead + i) == a)
{
index = i;
break;
}
}
for (int i = index; i < mSize; i++)
{
*(mHead + i) = *(mHead + i + 1);
}
mSize--;
}
int MyContainer::GetSize()
{
return mSize;
}
void MyContainer::DisplayAll()
{
cout << "\n";
for (int i = 0; i < mSize; i++)
{
cout << *(mHead + i) << " ";
}
}
int MyContainer::FindMissing()
{
int res[mSize];
int temp;
int flag = 0;
for (int i = 1; i <= mSize; i++)
{
flag = 0;
for (int j = 0; j < mSize; j++)
{
if (*(mHead + j) == i)
{
flag = 1;
break;
}
}
if (flag == 0)
{
temp = i;
break;
}
}
return temp;
}
int main()
{
const int cSize = 5;
int lArray[cSize] = { 2, 3, 7, 6, 8 };
MyContainer lContainer(lArray, cSize);
lContainer.DisplayAll();
lContainer.Delete(7);
lContainer.DisplayAll();
cout << "Size now is: " << lContainer.GetSize() << endl; lContainer.Add(-1);
lContainer.Add(-10);
lContainer.Add(15);
lContainer.DisplayAll();
cout << "Size now is: " << lContainer.GetSize() << endl;
cout << "First missing positive is: " << lContainer.FindMissing() << endl;
system("PAUSE"); return 0;
}
int res[mSize];
The size of the array mSize must be known at compile time. You cannot use a variable here. An option may be to define a macro with an largish value that will not exceeded.
static const int kLargeSize =100;
int res[kLargeSize];
Edited in response to the comments - const and constexpr are a better option than a macro.
Or even better, you can use std::vector - https://en.cppreference.com/w/cpp/container/vector

How to access elements of the array just by having the array's memory location? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, this is just few methods from my myArray.cpp class. It gives me error on
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
these above code(error - which is non-class type double). can anyone please help me? I'm trying to copy an array to the object array
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
}
void myArray::setSize(int value) {
if (value > 0) {
size = value;
}
}
void myArray::setData(int index, double value) {
if ((index >= 0) && (index < size)) {
arr[index] = value;
} else {
// cout << "NO!" << endl;
}
}
double myArray::getData(int index) const {
if ((index >= 0) && (index < size)) {
return arr[index];
} else {
return arr[size - 1];
}
}
That's my main.cpp class
#include <iostream>
#include "myArray.h"
//#include "myArray.cpp"
using namespace std;
int main (int argc, char **argv)
{
cout << "**************Testing Default Constructor*****************" << endl;
myArray A1;
cout << "A1: ";
A1.print();
cout << "**************Testing Alt Constructor 1*****************" << endl;
myArray A2(5,0);
cout << "A2: ";
A2.print();
cout << "**************Testing init*****************" << endl;
A2.init();
cout << "A2 after init: ";
A2.print();
int size = 5;
double *temp = new double[size];
for(int i = 0; i < size; i++)
{
temp[i] = i;
}
cout << "**************Testing Alt Constructor 2*****************" << endl;
myArray A3(temp, size);
cout << "A3: ";
cout << A3.getSize();
cout << endl;
cout << "Fe";
A3.print();
That's my myArray.cpp class
#ifndef MYARRAY_H_INCLUDED
#define MYARRAY_H_INCLUDED
/***************************************************************************
* myArray class header file
***************************************************************************/
class myArray
{
public:
myArray();
myArray(int,double);
myArray(double*, int);
~myArray();
int getSize() const;
bool equal(const myArray &rhs) const;
void setData(int index, double value);
void insert(int, double);
void remove(int);
double get(int);
void clear();
int find(double);
bool equals(myArray&);
void print() const;
void init();
double getData(int index) const;
// void init();
// void print() const;
void expand();
private:
int size;
double *arr;
void setSize(int value);
};
#endif // MYARRAY_H_INCLUDED
That's my myArray.cpp class where I'm getting the error in the default paramaterized constructor
#include "myArray.h"
#include <iostream>
using namespace std;
myArray::myArray() : size(0) {
// size = 10;
arr = new double [size];
}
/*myArray::myArray(int _size) : size(_size) {
// size = _size;
arr = new double [size];
for (int i = 0; i < size; i++) {
arr[i] = i;
}
} */
myArray::myArray(int _size, double value) : size(_size) {
// size = _size;
arr = new double [size];
for (int i = 0; i < size; i++) {
arr[i] = value;
}
}
/*myArray::myArray(myArray* temp, int size)
{
setSize(temp.getSize());
for (int i = 0; i < getSize(); i++) {
setData(i, temp.getData(i));
}
} */
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
//double arr[size];
// arr = new double[size];
// p = orig;
// for(int i = 0;i<size;i++)
// {
// arr[i] = orig[i];
// cout << arr[i] << " ";
// }
// cout << endl;
// setSize(size);
// for (int i = 0; i < getSize(); i++)
// setData(i, orig.getData(i));
// cout << "hell";
// for (int i = 0; i < size; i++) {
// arr[i] = myArray[i];
// cout << arr[i];
//}
// arr = myArray;
}
myArray::~myArray() {
delete [] arr;
}
int myArray::getSize() const {
return size;
}
void myArray::setSize(int value) {
if (value > 0) {
size = value;
}
}
void myArray::setData(int index, double value) {
if ((index >= 0) && (index < size)) {
arr[index] = value;
} else {
// cout << "NO!" << endl;
}
}
double myArray::getData(int index) const {
if ((index >= 0) && (index < size)) {
return arr[index];
} else {
return arr[size - 1];
}
}
void myArray::print() const {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
void myArray::expand() {
double *localArray = new double[size + 1];
for (int i = 0; i < size; i++) {
localArray[i] = arr[i];
}
localArray[size] = size;
delete [] arr;
setSize(size + 1);
arr = localArray;
// myArray = new int[size];
//
// //Is this a deep-copy or a shallow-copy?
// //Can you replace one with the other?
// //What are the advantages and disadvantages?
// for(int i=0; i < size; i++) {
// myArray[i] = localArray[i];
// }
// delete [] localArray;
}
bool myArray::equal(const myArray& rhs) const {
bool result(true);
if (getSize() != rhs.getSize()) {
result = false;
} else {
for (int i = 0; i < getSize(); i++) {
if (getData(i) != rhs.getData(i)) {
result = false;
}
}
}
return result;
}
void myArray::init()
{
cout << "Enter the " << size << " elements to populate the array " << endl;
for(int i = 0;i<getSize();i++)
{
int value;
cin >> value;
setData(i,value);
}
}
Sorry I somehow I thought you wanted help with a runtime error but you want help with the compile errors.
The compile error in this part of the code
myArray::myArray(double* orig, int size) {
setSize(orig.getsize());
for(int i = 0; i<getSize();i++)
setData(i,orig.getData(i));
is specifically about the orig.getSize() part. orig is of type double* (pointer to double) and pointers do not have member functions only classes do which is why the compiler says: "which is non-class type double"
Actually there is no way in c++ to know from a pointer to how many elements it points but luckily your function already has a parameter size which i guess is meant to pass in the size of the orig array. So that line should be setSize(size);
Now two lines lower you get a similar error on setData(i,orig.getData(i)); orig is still a double* so it still doesn't have member functions. The correct way is setData(i, orig[i]);
EDIT:
BTW, i quick look through the rest of your code shows me that your setSize method doesn't allocate an array of appropriate size so you should fix that to.

std::vector out of range for min-heap: C++

I've neglected to work on this code (or any other coding projects) for a while, so while I know what is basically wrong with the code, I've been having a hard time finding exactly where the vector is going out of range. I've been running gdb on it all morning to no avail. I'm trying to make a min-heap out of a vector "theData" in C++.
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
using std::swap;
using std::pair;
using std::make_pair;
class HeapBuilder {
private:
vector<int> data_;
vector< pair<int, int> > swaps_;
void WriteResponse() const {
cout << swaps_.size() << "\n";
for (int i = 0; i < swaps_.size(); ++i) {
cout << swaps_[i].first << " " << swaps_[i].second << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for(int i = 0; i < n; ++i)
cin >> data_[i];
}
void makeMinHeap(vector<int> &theData, int i, int n) {
int minIndex;
int left = 2*i;
int right = 2*i + 1;
if (left < n && theData.at(left) < theData.at(i)) {
minIndex = left;
}
else if (right < n && theData.at(right) < theData.at(i)) {
minIndex = right;
}
if (minIndex != i) {
swap(theData.at(i), theData.at(minIndex));
swaps_.push_back(make_pair(i, minIndex));
makeMinHeap(theData, minIndex, n);
}
}
void GenerateSwaps() {
swaps_.clear();
int size = data_.size();
for (int i = (size/2); i >= 0; i--) {
makeMinHeap(data_, i, size);
}
}
public:
void Solve() {
ReadData();
GenerateSwaps();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
You are not putting in a check for minIndex.
Look what happens when your left<=n and right <=n both fails, most likely when the whole recursion is about to stop, since you just check
minIndex != i
// ^-- default each time is garbage which in case last>n && right>n leaves it garbage
// hence when it comes to
if(minIndex!=i){
// It's actually true where it was suppose to break out n thus throws out_of_range
}
Quick n easy solution would be to add a flagcheck
bool flagcheck = false;
if(){ flagcheck = true; }
else if(){ flagcheck = true; }
if(minIndex!=i && flagcheck){}

when i was using pointers in function arguments i faced with an error

The error is this:
cannot convert int*' toint*' for argument 1' tobool permition(int*, int, int)'
Here in code i have a int board[n], and the user gives the 'n'...
i want to give my permition function this array so i had to give it by pointers because the length of it is not specified...So how can i solve this problem
Here is my code:
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
bool permition(int* board[],int place,int n_){
int m=place;
while(m!=0){
m--;
if(abs(abs(board[m]-board[place])-abs(m-place))==1
&& abs(m-place)<3 && abs(board[m]-board[place]))
return false;
}
return true;
}
void printBoard(int* board[],int n){
for(int i=0;i<n;i++)
cout << board[i]<< " ";
cout << endl;
}
int main()
{
int p=0;
int n;
cout << "plz: ";
cin >> n;
int board[n];
for(int i=0;i<n;i++)
board[i]=0;
while(p<n){
while((board[p]<n) && permition(board,p,n)==false)
board[p]+=1;
if(board[p]<n)
p++;
else{
p--;
board[p]+=1;
}
if(p==n && board[0]<n-1)
//it means the first number is not max so we should
//print and continue from fist again
{
printBoard(board,n);
p=0;
board[0]+=1;
}
}
system("PAUSE");
return 0;
}
Get rid of [] in the function definition of permition:
bool permition(int* board,int place,int n_)
See if that helps!
Change
bool permition(int* board[],int place,int n_)
to
bool permition(int const board[],int place,int n_)
The current argument declaration (first above) says that board is an array of pointers to int, which it isn't.
The [] ends up as a pointer, so you can alternatively write
bool permition(int const* board,int place,int n_)
This form has the advantage that you can use const also on the pointer, while with [] you have a pointer that can be changed but that looks like an array.
The disadvantage is that the declaration no longer communicates "array" to the reader.
As others have noted, the original code passes an array of int (which is treated as an int *) to a function that's declared to take a pointer to an array of int. Here's a corrected version, with some formatting changes that I hope will be helpful.
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
// Removed unused parameter n_.
bool permission(int board[], int place) {
int m = place;
// The original code could return false only if (place - m) < 3,
// so no need to test when (place - m) >= 3.
while (m-- > max(0, place - 3) {
int board_diff = abs(board[m] - board[place];
int index_diff = place - m; // Always >= 0
if (abs(board_diff - index_diff) == 1 && board_diff != 0) {
return false;
}
}
return true;
}
void printBoard(int board[], int n) {
for (int i = 0; i < n; i++) {
cout << board[i] << " ";
}
cout << endl;
}
int main() {
int p = 0;
int n;
cout << "plz: ";
cin >> n;
int board[n] = { 0 }; // Zeroes entire array.
while (p < n) {
// Never compare bool to true or false; just use !bool_var.
while ((board[p] < n) && !permission(board, p)) {
board[p]++;
}
if (board[p] < n) {
p++;
} else {
board[--p]++;
}
if (p == n && board[0] < (n - 1)) {
// The first number is not max so we should
// print and continue from first again
printBoard(board, n);
board[p = 0]++; // Assign and increment.
}
}
system("PAUSE");
return 0;
}
int board[];
is the same as
int *board;
so the solution in my guess is to write that
bool permition(int board[],int place,int n_)
void printBoard(int board[],int n)
You need to understand and to work more on pointers !

I am getting a Segmentation Fault with my For loops

I keep getting a segmentation fault error in my code
Header
#ifndef DUALSTK
#define DUALSTK
#include <deque>
using namespace std;
enum stackNumber {One, Two};
template <typename T>
class dualStack {
public:
// constructor. set counts to 0
dualStack() : dualStackElements(20, 0) {}
void push(const T& item, stackNumber n);
void pop(stackNumber n);
T& top(stackNumber n);
//const T& top(stackNumber n) const;
bool empty(stackNumber n) const;
int size(stackNumber n) const;
int getCount1() const {return count1;}
int getCount2() const {return count2;}
private:
deque<T> dualStackElements;
int count1, count2;
};
#endif // DUALSTK
main.cpp
#include <iostream>
#include <deque>
#include "dualstk.h"
using namespace std;
template <typename T>
T& dualStack<T>::top(stackNumber n) {
int num = 0;
if (n == 0) {
num = count1 - 1;
return num;
}
if (n == 1) {
num = 20 - count2;
return num;
}
}
template <typename T>
void dualStack<T>::push(const T& item, stackNumber n) {
if (n == 0) {
count1++;
dualStackElements[top(One)] = item;
}
if (n == 1) {
count2++;
dualStackElements[top(Two)] = item;
}
}
template <typename T>
void dualStack<T>::pop(stackNumber n) {
int item = 0;
int item2 = 0;
if (n == 0) {
item = dualStackElements[top(One)];
cout << item << " ";
count1--;
}
if (n == 1) {
item2 = dualStackElements[top(Two)];
cout << item2 << " ";
count2--;
}
}
template <typename T>
bool dualStack<T>::empty(stackNumber n) const {
return 1;
}
int main() {
dualStack<int> stack;
for(int i = 1; i < 21; i++) {
if(i % 2 == 0) {
stack.push(i, One);
}
else {
cout << i;
stack.push(i, Two);
}
}
cout << endl;
for (int j = 0; j < 10; j++)
stack.pop(One);
cout << endl;
for (int i = 0; i < 10; i++)
stack.pop(Two);
cout << endl;
cout << stack.getCount2();
cout << stack.getCount1();
cout << endl;
cout << "\n" << stack.top(One);
cout << stack.top(Two) << endl;
return 0;
}
Whenever I have one loop for my stack.pop it will work fine
but if I do a for loop right after I use one to do stack.pop it wont work
I am not sure what I did wrong to this
for (int j = 0; j < 10; j++)
stack.pop(One);
for (int i = 0; i < 10; i++)
stack.pop(Two);
function top() returns reference to local variable ‘num’. Its storage is on stack so the value would be modified when the function returns and then you use it as the index into dualStackElements. This may lead to access to invalid memory address.
I think you are misunderstanding what this does (or I misunderstood your code):
dualStackElements[top(One)] = item;
you have not declared an array of dualStackElements
Better to declare two dequeues instead.
deque<T> dualStackElementsOne;
deque<T> dualStackElementsTwo;
Your Top method needs some error checking. What if count1 is 0 (or count2 > 20)? You'd return a negative value and then use it as an index to your deque. And remove the return by reference!
top() method returns a reference to local variable num which was freed after the method call. But different OS have different limits on accessing illegal memory, sometimes, it is just OK in Linux.
In your constructor, there is no initializing operations for fields: count1, count2. The program always returns "Segmentation fault;" if I comment out "count1=count2=0;" in my modified constructor.
In order to get the stable result for a program, you should do a clean before a make. I don't know exactly why, but it did happen in my test run.