Здравствуйте, мне необходимо создать класс глобального прямоугольника, в котором создаются наследуемые классы прямоугольнички. При создании почему то не создаются, хотя если из класс глобальных прямоугольников убрать конструктор копий и деструктор, то все будет работать. Может кто-нибудь объяснить причину этого? Вот код:
#include <iostream>
#include <stdlib.h>
#include <time.h>
class GlobalRectangle
{
public:
GlobalRectangle(); // Конструктор
GlobalRectangle(const GlobalRectangle&); // Констуктор копий
~GlobalRectangle(); // Деструктор
void renderGlobalRectangle(); // Отрисовка прямоугольника
int getRows() { return mRows; }
int getColumns() { return mColumns; }
int getNRectangle() { return mnRectangle; }
int getGlobalRectangle(int r, int c) { return mGlobalRectangle[r][c]; }
void setGlobalRectangle(int r, int c, int value) { mGlobalRectangle[r][c] = value; }
int getRectangleCreated() const { return *mRectangleCreated; }
void setRectangleCreated(int rectangleNo) { *mRectangleCreated = rectangleNo; }
protected:
static const int mRows = 25;
static const int mColumns = 80;
int mGlobalRectangle[mRows][mColumns]; // Общий прямоугольник
private:
int* mRectangleCreated; // Количество созданных прямоугольничков
int mnRectangle; // Количество прямоугольничков
int x, y; //Координаты ячеек
};
GlobalRectangle::GlobalRectangle()
{
for (int r = 0; r < mRows; r++) // Заполнение прямоугольника единичками
for (int c = 0; c < mColumns; c++)
setGlobalRectangle(r, c, 1);
mnRectangle = rand() % 30 + 15; // Количество прямоугольничков
mRectangleCreated = new int(0); // Создано прямоугольничков: 0
}
GlobalRectangle::GlobalRectangle(const GlobalRectangle& rhs)
{
mRectangleCreated = new int;
*mRectangleCreated = rhs.getRectangleCreated();
}
GlobalRectangle::~GlobalRectangle()
{
delete mRectangleCreated;
mRectangleCreated = 0;
}
void GlobalRectangle::renderGlobalRectangle() // Отрисовка прямоугольника
{
for (int r = 0; r < mRows; r++)
{
for (int c = 0; c < mColumns; c++)
std::cout << getGlobalRectangle(r, c);
std::cout << std::endl;
}
}
class Rectangle : public GlobalRectangle
{
public:
Rectangle();
~Rectangle();
bool attemptCreateRectangle(GlobalRectangle rectangle); // Попытка создания прямоугольничка
int getAttempt() const { return mAttempt; }
void setAttempt(int attempt) { mAttempt = attempt; }
int getRectangleLength() const { return mRectangleLength; }
void setRectangleLength(int rectangleLength) { mRectangleLength = rectangleLength; }
int getRectangleHeight() const { return mRectangleHeight; }
void setRectangleHeight(int rectangleHeight) { mRectangleHeight = rectangleHeight; }
int getX() const { return mx; }
void setX(int x) { mx = x; }
int getY() const { return my; }
void setY(int y) { my = y; }
int getRectangleNo() const { return mRectangleNo; }
void setRectangleNo(int rectangleNo) { mRectangleNo = rectangleNo; }
int getMaxLength() const { return mMaxLength; }
int getMaxHeight() const { return mMaxHeight; }
int getMaxArea() const { return mMaxArea; }
int getMaxAttemptCreateRectangle() const { return mMaxAttemptCreateRectangle; }
private:
const int mMaxLength = 10; // Максимальная длина прямоугольничка
const int mMaxHeight = 10; // Максимальная ширина прямоугольничка
const int mMaxArea = 60; // Максимальная площадь прямоугольничка
const int mMaxAttemptCreateRectangle = 5; // Попыток создания прямоугольничка
int mRectangleLength, mRectangleHeight; // Длина и ширина прямоугольничка
int mx, my; //Координаты ячеек
int mAttempt = 0; // Попытка
int mRectangleNo; // Номер прямоугольничка
};
Rectangle::Rectangle()
{
setRectangleNo(0);
}
Rectangle::~Rectangle()
{
}
bool Rectangle::attemptCreateRectangle(GlobalRectangle rectangle) // Попытка создания прямоугольничка
{
bool isSuccess = false;
int rectangleLength, rectangleHeight; // Длина и ширина прямоугольничка
int x, y; // Координаты ячеек
int maxLength = getMaxLength(); // Максимальная длина
int maxHeight = getMaxHeight(); // Максимальная высота
int maxArea = getMaxArea(); // Максимальная площадь
setAttempt(mAttempt++); //Увелечение номера попытки
x = rand() % mRows; // Случайная координата x
y = rand() % mColumns; // Случайная координата y
rectangleLength = rand() % maxLength + 3; // Длина прямоугольничка
rectangleHeight = rand() % maxHeight + 3; // Ширина прямоугольничка
// Проверка максимальной площади
if ((rectangleLength * rectangleHeight) > maxArea)
return isSuccess;
// Проверка умещается прямоугольничек в общем прямоугольнике или нет
if (((x + rectangleLength) > mRows) || ((y + rectangleHeight) > mColumns))
return isSuccess;
// Проверка не мешается ли прямоугольничек другим прямоугольничкам
for (int r = x - 1; r < x + rectangleLength + 1; r++)
for (int c = y - 1; c < y + rectangleHeight + 1; c++)
{
int value = rectangle.getGlobalRectangle(r, c);
if (value == 0)
return isSuccess;
}
setRectangleLength(rectangleLength);
setRectangleHeight(rectangleHeight);
setX(x);
setY(y);
setAttempt(0); // Сброс количества попыток
int rectangleNo = rectangle.getRectangleCreated() + 1; // Присвоение номера прямоугольничка
rectangle.setRectangleCreated(rectangleNo); // Увеличение количества прямоугольничков
setRectangleNo(rectangleNo);
isSuccess = true;
return isSuccess;
}
int main()
{
GlobalRectangle globalRectangle;
int nRectangle = globalRectangle.getNRectangle(); // Количество создаваемых прямоугольничков
std::cout << "nRectangle: " << nRectangle << std::endl;
// Выделяется память для объектов класса Rectangle в количестве nRectangle
Rectangle *rectangleNo = new Rectangle[nRectangle];
for (int i = 0; i < nRectangle; i++)
{
int maxAttempt = rectangleNo[i].getMaxAttemptCreateRectangle();
int attempt = rectangleNo[i].getAttempt();
for (int a = 0; a < maxAttempt; a++)
{
bool isSuccess = rectangleNo[i].attemptCreateRectangle(globalRectangle);
if (isSuccess == true)
{
int x = rectangleNo[i].getX();
int y = rectangleNo[i].getY();
int rectangleLength = rectangleNo[i].getRectangleLength();
int rectangleHeight = rectangleNo[i].getRectangleHeight();
for (int r = x; r < x + rectangleLength; r++) // Создание прямоугольничка
for (int c = y; c < y + rectangleHeight; c++)
globalRectangle.setGlobalRectangle(r, c, 0);
break;
}
}
}
globalRectangle.renderGlobalRectangle();
int rectangleCreated = globalRectangle.getRectangleCreated();
std::cout << "Rectangle Created: " << rectangleCreated << std::endl;
for (int i = 0; i < nRectangle; ++i)
{
std::cout << "rectangleNo[" << i << "]: " << rectangleNo[i].getRectangleNo() << std::endl;
}
delete[] rectangleNo;
char response;
std::cin >> response;
return 0;
}
Вывод с консоли:
nRectangle: 26
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
Rectangle Created: 0
rectangleNo[0]: 0
rectangleNo[1]: 0
rectangleNo[2]: 0
rectangleNo[3]: 0
rectangleNo[4]: 0
rectangleNo[5]: 0
rectangleNo[6]: 0
rectangleNo[7]: 0
rectangleNo[8]: 0
rectangleNo[9]: 0
rectangleNo[10]: 0
rectangleNo[11]: 0
rectangleNo[12]: 0
rectangleNo[13]: 0
rectangleNo[14]: 0
rectangleNo[15]: 0
rectangleNo[16]: 0
rectangleNo[17]: 0
rectangleNo[18]: 0
rectangleNo[19]: 0
rectangleNo[20]: 0
rectangleNo[21]: 0
rectangleNo[22]: 0
rectangleNo[23]: 0
rectangleNo[24]: 0
rectangleNo[25]: 0
Начнём копать отсюда:
При создании почему то не создаются, хотя если из класс глобальных прямоугольников убрать конструктор копий и деструктор, то все будет работать
Вопрос первый: где вообще единственному экземпляру GlobalRectangle может потребоваться копирующий конструктор?
Ответ находится в попытке создания вложенного прямоугольника:
bool Rectangle::attemptCreateRectangle(GlobalRectangle rectangle) {
...
int rectangleNo = rectangle.getRectangleCreated() + 1; // Присвоение номера прямоугольничка
rectangle.setRectangleCreated(rectangleNo); // Увеличение количества прямоугольничков
...
}
В свою очередь,
void setRectangleCreated(int rectangleNo) { *mRectangleCreated = rectangleNo; }
запишет в указатель на число созданных прямоугольников новое значение.
У меня сладывается ощущение, что вргументом должна быть ссылка на общий прямоугольник, а не копия, но продолжу.
Если убрать написанный копирующий конструктор, будет создан копирующий конструктор по умолчанию. Разница в том, что созданный по умолчанию скопирует указатель (не создаст новый, а скопирует тот же самый адрес). Тогда все копии GlobalRectangle
будут обращаться к одному и тому же значению счётчика, и, несмотря на порицания со стороны старшего разработчика, код будет работать.
Однако злить старшего разрабочика не стоит; поставим конструктор на место и вернёмся ко второму вопросу: а что же, собственно, не работает?
Вызов в main:
rectangleNo[i].attemptCreateRectangle(globalRectangle);
передаёт globalRectangle
по значению - т.е. делает копию, и, в силу правильно(!) написанного копирующего конструктора, этот вызов не меняет состояние оригинала. Поэтому ближе к концу
int rectangleCreated = globalRectangle.getRectangleCreated();
возвращает 0, т.к. оригинал не в курсе, что в его копиях создавались прямоугольники.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть меню, в меню несколько пунктов, как сделать так чтобы при клике на какой-то из них, background менял цвет(допустимсерый), и оставался серым...
Здравствуйте! Подключаю inputMask с алиасом hh:mm:ss если ввел к примеру 12:10:20, ставлю курсор на часы и удаляю символы - очищается только ячейка часовА...