Базовый класс Array и производные классы SortArray и XorArray

129
03 августа 2019, 16:50

Помогите закончить программу пожалуйста. Необходимо создать базовый класс Array с виртуальными методами сложения и поэлементной обработки foreach() и производные от него классы Sort Array и XorArray. В SortArray операцию сложения реализовать как пересечение множеств, а поэлементную обработку извлечением корня каждого элемента массива. В XorArray сложение как исключающее или, а поэлементная обработка - сортировка массива. Я уже задал foreach() для обоих классов (для второго не уверен, что верно). Не могу реализовать сложение, компилятор жалуется ещё в базовом классе. Ниже привиден код. Ошибка в SortArray::add - error: cannot allocate an object of abstract type 'Array' (не единственная)

#ifndef ARRAY
#define ARRAY
#include <iostream>
#include <iomanip>
#include <cstring>
#include <stdexcept>
using namespace std;
class Array{
public:
    double *arr;
    size_t sz;
public:
    Array () {
        arr = nullptr;
        sz = 0;
    }
    Array (size_t _sz){
        arr = new double[_sz];
        sz = _sz;
    }
    Array (double *a, size_t s){
        sz = s;
        arr = new double [s];
        for (size_t i = 0; i < sz; i++)
            arr[i] = a[i];
    }
    Array (const Array& other){
        sz = other.sz;
        arr = new double [sz];
        for (size_t i = 0; i < sz; i++)
            arr[i] = other.arr[i];
    }
    virtual ~Array (){
        delete [] arr;
    }
    void print() const {
        for(size_t i = 0; i < sz; ++i)
            cout << setw(6) << setiosflags(ios::showpoint) << setprecision(3) << arr[i];
        cout << endl;
    }
    double& operator[](size_t i) {
        if(i < 0 || i >= sz) throw out_of_range("Exit for size");
        else return arr[i];
    }
    size_t resize(size_t newsz) {
        if(newsz < sz)
            return sz;
        else {
            double *newarr = new double [newsz];
            for(size_t i = 0; i < sz; ++i)
                newarr[i] = arr[i];
            for(size_t i = sz; i < newsz; ++i)
                newarr[i] = 0;
            sz = newsz;
            delete [] arr;
            arr = newarr;
            return newsz;
        }
    }
   size_t size() const {
        return sz;
   }
    virtual Array& add (Array&) const = 0;
    virtual void foreach () = 0;
};
#endif // ARRAY

//SortArray методы
    SortArray& add (const Array&other){
        Array *temp;
        for(size_t i = 0; i < sz; i++)
            temp [i] = arr[i];
        for(size_t j = sz; j < other.sz; j++)
            temp [j] = other.arr[j - sz];
        return temp;
    }
    void foreach(){
    double temp;
        for (size_t i = 0; i < sz - 1; i++) {
         for (size_t j = 0; j < sz - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
 }
// XorArray методы
    XorArray& add (const Array &x){
        for (size_t i = 0; i < arr; i++)
            x.arr[i] = arr[i] ^ arr[i];
    }
    void foreach(){
        double *newarr = new double[sz];
        for (size_t i = 0; i < sz; i++) {
            newarr[i] = arr[i];
        }
        for (size_t i = 0; i < sz; i++) {
            arr[i] = sqrt(newarr[i]);
        }
    }
Answer 1

Во первых нет нужды делать базовый класс абстрактным, обьявляя в нем две чисто_виртуальные функции. Вы должны их определять, чтобы базовый класс по своему выполнял и имели бы возможность создавать обьекты базового класса.

virtual Array&  Array::add (Array&) const;
virtual void Array::foreach ();

Во вторых вы функцию определяете с помощью битовой операции, но битовую операцию вы пытаетесь выполнять на переменных типа double, что невозможно. Правда, я не ясно понел условие задачи, но можно сделать, например, так:

// XorArray методы
// для начала сделайте члены класса защищенными, а не закрытыми
Array& XorArray::add(const Array &x) override
{
    for (size_t i = 0; i < sz; i++) {
         double d1 = arr[i], d2 = x.arr[i];
         int x1 = d1, x2 = d2;
         arr[i] = (x1 ^ x2) + (d1 - x1) + (d2 - x2);
    }
    return *this;                     
}

И еще вы определяете копирующий конструктор неправильно: Нужно уничтожать старый массив, если размер копируемого обьекта различается, и после создавать новый, в обратном случаи просто присвоения:

Array (const Array& other){
    if ( sz != other.sz) {
        delete arr;
        sz = other.sz; 
        arr = new double [sz];            
    }               
    for (size_t i = 0; i < sz; i++)
        arr[i] = other.arr[i];
}   

Не смотрел есть ли еще другие ошибки?.. Но нужно также определять оператор присваивания

Answer 2

Вы неправильно объявили методы наследников. Сигнатуры виртуальных методов должны совпадать с сигнатурами базового класса, т.е. объявление наследника должно быть примерно таким:

class SortArray: public Array{
  ...
  Array& add (Array&) const override; 
  void foreach() override;
  ...
};

Чтобы не допускать таких ошибок, используйте override в наследниках - при этом в случае ошибки компилятор прямо скажет, что в базовом классе нет виртуального метода с такой сигнатурой.

READ ALSO
Что означает знак &ldquo;&amp;&rdquo; в этой строке?

Что означает знак “&” в этой строке?

Что означает знак "&" в этой строке?

140
Разбить файлы на архивы

Разбить файлы на архивы

Необходимо разбить большое количество файлов на архивыНо неизвестно, сколько их может быть

121
проблемы java hibernate

проблемы java hibernate

первый раз делаю hibernate возникла ошибкаВ java новичок подскажите куда копать

122