Gthoma2
Gthoma2

Reputation: 707

How is this derived class abstract?

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..

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.

Upvotes: 1

Views: 1084

Answers (1)

JasonD
JasonD

Reputation: 16612

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.

Upvotes: 4

Related Questions