I have class NumberArray in NumberArray.h
class NumberArray
{
private:
double *aPtr;
int arraySize;
public:
NumberArray(NumberArray &);
NumberArray(int size, double value);
NumberArray() { if (arraySize > 0) delete[] aPtr; }
void print() const;
void setValue(double value);
};
In my cpp file, NumberArray.cpp I define the constructor
NumberArray(NumberArray &)
by
NumberArray::NumberArray(NumberArray &obj)
{
arraySize = obj.arraySize();
aPtr = new double[arraySize];
for (int index = 0; index < arraySize; index++)
{
aPtr[index] = obj.aPtr[index];
}
}
From all I've learned, this should work. However I'm receiving an error "expression preceeding parenthesis of apparent call must have (pointer-to-) function type.
I thought I already did have a point-to function type...
Can someone help me with where I went wrong?
arraySize = obj.arraySize();
arraySize is a class member. It is not a class method. This should be:
arraySize = obj.arraySize;
Related
I was trying yo create my own array class (similar to std::vector) just for fun but there is some problem...
The Array class code itself works and compiles successfully but throws an error if i try to instantiate an object of Array class.
#include<iostream>
template<typename type, int size>
class Array
{
private:
type _mArray[size] = new type[size];
public:
int Access(int index)
{
return _mArray[index];
}
int Len()
{
return size;
}
void Insert(int index, type val)
{
_mArray[index] = val;
}
~Array()
{
delete[] _mArray;
}
};//All code above compiles successfully
int main()
{
Array<int, 2> name; //this line throws an error
}
I am a bit new to C++ so if someone can explain then I will be very thankful....
Btw here is the error
Array initializer must be an initializer list
type _mArray[size] = new type[size];
The template instantiates with: type is int, and size is 2. Therefore, this becomes:
int _mArray[2] = new int[2];
This obviously does not make much sense. If you put this, verbatim, in your main() your C++ compiler will also serve you with the same complaint.
It's clear that the intent here is, simply:
type _mArray[size];
And nothing else.
P.S. Now, let's go back and reread what the suffering C++ compiler was struggling to communicate here:
Array initializer must be an initializer list
int _mArray[2] is, obviously, an array. There's an = stuck after it. Ok, this must be array initialization. How do you initialize an array in C++? With a braced initialization list, of course. This would be something like this, for example:
int _mArray[2]={1, 2};
The C++ compiler saw nothing of that kind, and was trying to tell you that.
#include<iostream>
template<typename type, int size>
class Array
{
private:
type * _mArray ;
public:
int Access(int index)
{
return _mArray[index];
}
int Len()
{
return size;
}
Array()
{
_mArray = new type[size];
}
~Array()
{
delete[] _mArray;
}
int& operator[](int index){
return _mArray[index];
}
};//All code above compiles successfully
int main()
{
Array<int, 2> name;
name[0] = 1024;
name[1] = 100;
for(int i= 0; i< name.Len(); i++)
{
std::cout<< name[i] << std::endl;
}
}
You can get it to build using the following minimal change:
## -4,7 +4,7 ## template<typename type, int size>
class Array
{
private:
- type _mArray[size] = new type[size];
+ type* _mArray;
public:
int Access(int index)
{
## -18,6 +18,10 ## class Array
{
_mArray[index] = val;
}
+ Array()
+ {
+ _mArray = new type[size];
+ }
~Array()
{
delete[] _mArray;
Basically, you should be initializing the array in your constructor, and store a pointer to it as a class member. The following code builds:
#include<iostream>
template<typename type, int size>
class Array
{
private:
type* _mArray;
public:
int Access(int index)
{
return _mArray[index];
}
int Len()
{
return size;
}
void Insert(int index, type val)
{
_mArray[index] = val;
}
Array()
{
_mArray = new type[size];
}
~Array()
{
delete[] _mArray;
}
};//All code above compiles successfully
int main()
{
Array<int, 2> name; //this line throws an error
}
I'm trying to create a chess engine, so I made a Board class (only showing the h file because the implementation is pretty straight forward):
class Board {
private:
Piece* board[SIZE][SIZE];
bool turn;
public:
Board();
Piece* getBoard() const;
void printBoard() const;
};
The idea is to make a 2D array filled with different pieces.
Obviously, I made a Piece class as well (a parent class to all other pieces):
class Piece {
protected:
bool color;
int PosX;
int PosY;
public:
Piece(const bool c, const int x, const int y);
~Piece();
virtual int tryMove(int toX, int toY, Board &board) const = 0;
virtual char toChar() const = 0;
}
I made an EmptyPiece class to try and initialize the array, but I just can't figure out how to fill the array with those pieces.
the h file for EmptyPiece:
class EmptyPiece : protected Piece {
public:
EmptyPiece(const bool c, const int x, const int y);
char toChar() const;
int tryMove(int toX, int toY, Board& board) const;
};
and this is how I'm trying to initialize the array:
Board::Board()
{
turn = true;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
board[i][j] = EmptyPiece(0, i, j);
}
}
}
which results in an error:
E0413 no suitable conversion function from "EmptyPiece" to "Piece *" exists
On the right side of the following statement:
board[i][j] = EmptyPiece(0, i, j);
EmptyPiece(0, i, j) created a temporary object with type EmptyPiece, which is also convertible to type Piece. But the left side requires a variable of type Piece*, i.e. a pointer to a Piece object. In general, you can't assign a variable of type T to another variable of type T*.
You can fix it with the following version:
board[i][j] = new EmptyPiece(0, i, j);
But you need to remember to delete the objects you new'ed.
I am getting passing 'const Array' as 'this' argument of 'int& Array::operator[](int)' discards qualifiers when compiling under Dev C++. If I compile using gcc on cygwin I've got a few error messages of this type:
error: extra qualification ‘Array::’ on member ‘Array’ [-fpermissive]
Can you tell me what is the reason for the error? I've spent a lot of time on this code and still can't make it work correctly.
#include<iostream>
using namespace std;
class Array
{
int *m_ptr;
int m_size;
public:
Array(int sz)
{
cout<<"constructor\n";
m_size = sz;
m_ptr = new int[sz];
}
~Array()
{
cout<<"Delete\n";
delete[] m_ptr;
}
int& operator[] (int j)
{
cout<<"Operation []\n";
return m_ptr[j];
}
void Array::copy(const Array& ar)
{
m_size = ar.m_size;
m_ptr = new int[m_size];
int *ptr = ar.m_ptr;
int j;
for(j = 0;j < m_size; j++)
m_ptr[j] = ptr[j];
}
Array::Array(const Array& ar)
{
copy(ar);
}
void Array::print(const Array& ar)
{
int i;
int len = ar.m_size;
for(i = 0;i < len;i++)
cout<<ar[i]<<" ";
cout<<endl;
}
};
int main()
{
Array a1(10);
Array a2(5);
int i;
for(i = 0;i < 10;i++)
{
a1[i] = 1;
if(i < 5) a2[i] = 2;
}
print(a1);
return 0;
}
Furthermore, the book I am reading also has the function
Array& operator= (const Array& ar)
{
delete m_ptr;
copy(ar);
return *this;
}
I do not understand why do we need to use this function.
Just change
void Array::copy(const Array& ar)
to
void copy(const Array& ar)
The class scope qualifier is only needed for function definitions appearing outside of the class declaration.
Issue 1
You don't need the Array:: in
void Array::copy(const Array& ar) { ... }
when the function is defined inside the class definition. It can simply be
void copy(const Array& ar) { ... }
You need the Array:: part only when the function is defined outside the class definition.
Issue 2
In print, you have the line:
cout<<ar[i]<<" ";
Since ar is a const object and the operator[]() function is not a const member function, the compiler doesn't like it. What you should do is provide two overloads of the operator[] function -- one for const objects and one for non-const objects.
int& operator[] (int j)
{
return m_ptr[j];
}
int operator[] (int j) const
{
return m_ptr[j];
}
Then, you can use the array operator to access the elements of a const object as well as access and modify the elements of a non-const object.
I have a template vector class. This is how a part of it looks like:
template<class Type>
class Vector
{
public:
Vector(int size)
{
MyTime = new Type[size];
m_size = size;
m_current = -1;
}
void set(int i,Type &data)
{
data[i]=Mytime[i];
}
private:
Type* MyTime;
int m_size;
int m_current;
};
Then i wish to use the set method above to set the value into a string "records".
for(int i=0 ; i<count ; i++)
{
records.set(i)=dateList.get(i)+timeList3.get(i);
}
But it gives me two errors:
1. too few argument in function call.
2. expression must be a modifiable lvalue.
Both errors appear at the records.set(i).
The declaration of "records" is:
Vector<string> records(100);
This makes me quite confuse. May I know how to solve it?
I think that records.set(i)=dateList.get(i)+timeList3.get(i); is supposed to be this:
records.set(i, dateList.get(i) + timeList3.get(i));
too few argument in function call. - In your example you only pass i, meanwhile there are two arguments required to set
expression must be a modifiable lvalue - set() return void, it's not a method that returns a modifiable lvalue.
Meanwhile, you vector class does some weird things. This is a basic template vector class.
template <typename T>
class Vector
{
public:
Vector(int size) : data(new T[size]) {}
void Set(int index, const T& val) { data[index] = val; }
T Get(int index) { return data[index]; }
private:
T* data;
}
So I have an abstract base class, Collection. I understand that it is abstract because it declares at least one pure virtual function.
I have a subclass of Collection, OrderedCollection, which declares those functions exactly in it's own header file. I then define those exact same functions in OrderedCollection's Source file.
Here is the code:
Class Collection.h
class Collection {
public:
virtual Collection& add(int i, int index) = 0; //pure virtual
virtual Collection& remove(int i) = 0; //pure virtual
virtual Collection& operator=(const Collection& other)=0; //pure virtual
virtual int& operator[](int i) = 0; //pure virtual
Collection& iterate(void (*pFunc)()); //Function takes pointer to function as argument
bool contains(int i);
virtual Collection& copy();
virtual ~Collection();
int size() { return size; }
int capacity() { return capacity; }
//virtual void swap(Collection& other);
protected:
Collection(){}
std::vector collectionVec;
int size;
int capacity;
};
Derived class OrderedCollection.h:
class OrderedCollection : public Collection
{
public:
OrderedCollection& add(int i, int index);
OrderedCollection& remove(int i);
OrderedCollection& operator=(const OrderedCollection& other);
int& operator[](int i);
OrderedCollection();
//OrderedCollection::OrderedCollection(int pFirst, int pLast, int pSize, int pCapacity, std::vector<int> passedVec);
//OrderedCollection(const OrderedCollection& other); //Copy constructor
virtual ~OrderedCollection();
virtual OrderedCollection& copy(OrderedCollection& passedCollection);
protected:
//int* first;
//int* last;
int first;
int last;
OrderedCollection& grow(); //Utility Function
};
aaand OrderedCollection.cpp:
#include "OrderedCollection.h"
OrderedCollection& OrderedCollection::add(int i, int index){
if(size == capacity){ //If vector is full
}
return *this;
}
OrderedCollection& OrderedCollection::remove(int i){
if(first <= last){
for(int j = first; j <= last; j++){
if(collectionVec.at(j) == i){
collectionVec.erase(j);
last--;
}
}
}
/*for(int j = 0; j < collectionVec.size(); j++){
if(collectionVec.at(j) == i)
} */
return *this;
}
OrderedCollection& OrderedCollection::operator=(const OrderedCollection& other){
if (this != &other) // protect against invalid self-assignment
{
// 1: allocate new memory and copy the elements
std::vector<int> *new_vector = new std::vector<int>(other.capacity);
std::copy(other.collectionVec, other.collectionVec + other.capacity, new_vector);
// 2: deallocate old memory
collectionVec.clear();
// 3: assign the new memory to the object
collectionVec = *new_vector;
size = other.size; //wtf
capacity = other.capacity; //wtf
delete new_vector;
}
// by convention, always return *this
return *this;
}
int& OrderedCollection::operator[](int i){ //is return type correct? It makes more sense to have a return type of int or int&, right?
int temp = 0;
if(first <= last){
if(collectionVec.at(first + i) != NULL){ //Need to redo this
return collectionVec.at(first + i);
}
}
return temp;
}
OrderedCollection::OrderedCollection() : Collection()
{
//first = &collectionVec.at(2);
//last = &collectionVec.at(1);
//Crossed at construction
first = 2;
last = 1;
}
OrderedCollection::~OrderedCollection(void)
{
//first = NULL;
//last = NULL;
collectionVec.clear();
}
OrderedCollection& OrderedCollection::grow(){
int newFirst = capacity / 2;
std::vector<int> *new_vector = new std::vector<int>(2 * capacity);
std::copy(collectionVec, collectionVec+size, new_vector->begin() + newFirst); //Want to return iterator pointing to
collectionVec = new_vector;
first = newFirst;
last = first + size;
capacity = collectionVec.size;
delete new_vector;
return *this;
}
OrderedCollection& OrderedCollection::copy(OrderedCollection& passedCollection){
OrderedCollection* temp = new OrderedCollection() //ERROR is here. VS highlights constructor method
return *this;
}
Now the issue comes when I am trying to create either a value identifier of type OrderedCollection within this last copy() here. As I understand it, I shouldn't be allowed to do this if the class is abstract (so clearly it is abstract, also VS tells me so). But there is another issue; I get the same error when I try to create a new OrderedCollection object and assigning it to temp. The above intialization is fine according VS (no complaints from the IDE, although it doesnt help me any). But I can't figure out why it's regarding this class as abstract.
Correct me if I'm wrong, but this should cover all of the bases in making sure that this derived class is NOT abstract..
There are no pure virtual functions declared within the derived class
All functions that were pure virtual in the base class, have been overridden in the derived class.
All of the overridden functions match the relevant function argument signature & return type, as originally declared in the base class.
The error exactly is, Error: object of abstract class type "OrderedCollection" is not allowed... And this is when I try to assign a pointer object to a new instance of OrderedCollection within this copy() method at the bottom.
Let me post my Collection.cpp file below:
#include "Collection.h"
Collection::Collection()
{
size = 0;
capacity = 4;
collectionVec.resize(capacity);
}
Collection::~Collection()
{
}
Collection& Collection::iterate(void (*pFunc)()){
return *this;
}
bool contains(int i){
return true;
}
Edit: Added Collection.cpp file and updated some fixes I've made in regards to mismatching function parameters.
virtual Collection& operator=(const Collection& other)=0;
is not being overridden in the child class, because:
OrderedCollection& operator=(OrderedCollection& other);
Has a different signature.
The difference is not just the 'const', but the actual type. The overridden class must also take a Collection, and not the derived OrderedCollection.