Я просмотрел несколько статей, которые кажутся похожими на мои проблемы, возникающие у меня при выполнении домашней работы для введения в C++, но я все еще не могу найти решение.
Я пытаюсь перегрузить оператор +, чтобы увеличить пассажировместимость на int n. Также перегрузка оператора ++ для увеличения пассажировместимости на 1.
Обратите внимание, что в моем классе происходит полиморфизм, у меня есть Ship (базовый), CruiseShip (производный).
Конструктор круизного корабля:
CruiseShip::CruiseShip(string name, string year, int passengers) : Ship(name, year)
{
maxPassengers = passengers;
}
Перегрузки оператора:
CruiseShip& CruiseShip::operator+(int n) const
{
maxPassengers += n;
return *this;
}
CruiseShip& CruiseShip::operator++() // prefix
{
++maxPassengers;
return *this;
}
CruiseShip CruiseShip::operator++(int) // postfix
{
CruiseShip temp(*this);
operator++();
return temp;
}
Главный:
int main()
{
//Create objects, pointers
Ship *ships[3] = {new Ship("Titania", "2020"), new CruiseShip("Lusia", "2029", 200), new CargoShip("Luvinia", "2025", 500)};
//Print out ships
for(Ship *s : ships)
{
s -> print();
cout << endl;
}
//Reset a ships passenger, capacity
//I've tried testing each individually and all 3 still end up with segmentation errors
ships[1] = ships[1] + 5; //segmentation error related to this
ships[1]++; // segmentation error related to this
++ships[1]; // segmentation error related to this
//Print out ships
for(Ship *s : ships)
{
s -> print();
cout << endl;
}
//deallocate
return 0;
}
Массив не содержит объектов, он содержит указатели. Итак, то, что вы делаете, - это арифметические операции с указателями, которые не связаны с вашими перегруженными операторами.
@ S.M. Итак, насколько я понимаю, я, по-видимому, выполняю эти операции с адресом, на который указывает указатель, а не с самим объектом? Если да, сможет ли это исправить разыменование?
Попробуй сам.
Я попытался отрегулировать его, но, похоже, у меня все еще возникает ошибка. Хм :/





Чтобы добиться этого, используйте виртуальные функции. Но мы сталкиваемся с проблемой, что базовый класс не может вернуть объект производного класса. Итак, чтобы решить эту проблему, мы можем просто заставить класс Derived вместо этого возвращать базовый класс. Итак, вот пример кода:
class Ship
{
public:
Ship(string name, string year)
{
this->name = name;
this->year = year;
}
virtual Ship & operator + (int n)
{
return *this;
}
virtual Ship & operator ++()
{
return *this;
}
virtual Ship & operator ++ (int i)
{
return *this;
}
public:
string name;
string year;
};
class CruiseShip : public Ship
{
public:
virtual Ship& operator+(int n)
{
maxPassengers += n;
return *this;
}
virtual Ship & operator++() // prefix
{
++maxPassengers;
return *this;
}
virtual Ship & operator++(int) // postfix
{
CruiseShip temp(*this);
operator++();
return temp;
}
CruiseShip(string name, string year, int passengers) : Ship(name, year)
{
maxPassengers = passengers;
}
int maxPassengers;
};
Создание виртуальной функции как в базовом, так и в производном классах позволяет иметь определение независимо от типа корабля И по-прежнему позволяет нам определять виртуальную функцию по-разному в производном классе.
Обратите внимание, что перегруженные операторы CruiseShip возвращают Ships, а не CruiseShips. Это удовлетворяет требованию иметь тот же тип возвращаемого значения виртуальной функции.
Затем в main единственные изменения, которые вам нужно будет сделать, - это разыменовать указатель и поместить этот разыменованный указатель в круглые скобки следующим образом: (*Ship[1])++
operator+ нужен только один аргумент, если это функция-член, каковым кажется. Тем не менее, operator+ почти всегда не должен быть членом, поэтому предоставление его в качестве функции-члена является недостатком дизайна (и он должен возвращать новое значение, а не ссылку; operator+ в том виде, в каком он написан, подходит для operator+=, а не operator+).
Мой класс корабля не включает его, в основном потому, что я не уверен, как я это сделаю, я подумал об использовании виртуального, но это означало бы, что заголовок функции должен быть таким же (что не сработает b / c возврата тип). Честно говоря, я не уверен, как разыменовать свои указатели, я пробовал несколько разных способов, и все они все еще заканчиваются ошибками сегментации.
Если вы хотите сделать это так, как вы это делаете, вам придется либо объявить свой CruiseShip как CruiseShip, либо сделать виртуальных перегруженных операторов. Это из-за типа, который вы используете. Если вы выбираете виртуальный маршрут, вы правы, Корабль должен возвращать тот же тип. Чтобы решить эту проблему, необходимо, чтобы все конкретные классы перегружали виртуальную функцию ИЛИ возвращали сам Ship, ничего не делая с ним. Но он должен возвращать тот же тип.
Если я должен вернуть CruiseShip для моего оператора ++, но CruiseShip не входит в сферу ответственности Корабля. Я не понимаю, как будет работать виртуальная функция, потому что в классе корабля вы не сможете записать ее как virtual CruiseShip operator++(int). В классе CruiseShip это необходимо.
Ах. Тогда вы правы, вероятно, это не должно быть виртуальным. Я думаю, что лучшим способом было бы объявить 3 разных указателя для кораблей. Таким образом, они не относятся к типу Ship. Я продемонстрировал это, и это сработало. Я выложу свое решение
Да ... проблема в том, что домашнее задание велело нам создать массив указателей кораблей, иначе я бы точно не сделал это таким образом.
@Amai Я обновил ответ и подтвердил, что он работает.
Насколько я могу судить, ваш
operator+не должен даже компилироваться. Разместите минимальный воспроизводимый пример.