• Как правильно выстроить логику кода с соблюдением принципов ООП?

    @lipa44 Автор вопроса
    // cube.h
    ...
    #pragma once
    
    #include <iostream>
    #include <vector>
    #include <unistd.h> // для sleep и flush
    #include "checkCubeFunctions.h"
    
    #define Plane vector<vector<MiniCube*>>
    #define RightCenter RightPlane[1][1]->RightColor()
    #define LeftCenter LeftPlane[1][1]->LeftColor()
    #define UpCenter UpPlane[1][1]->UpColor()
    #define DownCenter DownPlane[1][1]->DownColor()
    #define FrontCenter FrontPlane[1][1]->FrontColor()
    #define BackCenter BackPlane[1][1]->BackColor()
    
    #include "miniCube.h" // то, из чего состоит кбуик
    #include "cubeSolving.h" // алгоритмы решения
    #include "rotates.h" // повороты
    #include "additional.h" // прочие вспомогательные функции
    ...
    
    class rubikCube {
    private:
    
    //    unsigned int FirstStepCounter = 0, SecondStepCounter = 0, ThirdStepCounter = 0,
    //            FourthStepCounter = 0, FifthStepCounter = 0, SixthStepCounter = 0, SeventhStepCounter = 0;
    
        // В arr мы храним "слои" нашего кубика, в каждом из которых есть 3 вектора по 3 мини-кубика
        vector<vector<vector<MiniCube>>> arr;
    
        // Грани кубика
        Plane UpPlane;
        Plane DownPlane;
        Plane LeftPlane;
        Plane RightPlane;
        Plane FrontPlane;
        Plane BackPlane;
    ...


    // solution.h
    #pragma once
    
    #include "rubikCube.h"
    #include "rotates.h" // повороты
    #include "checkCubeFunctions.h"
    
    using namespace std;
    
    // class rubikCube; пишет  Can't resolve type 'rubikCube'
    
    class cubeSolving {
    private:
        int FirstStepCounter = 0, SecondStepCounter = 0, ThirdStepCounter = 0, FourthStepCounter = 0,
                FifthStepCounter = 0, SixthStepCounter = 0, SeventhStepCounter = 0;
    
        // хотелось бы тут хранить rubikCube cube;
        // но он выдаёт Can't resolve type 'rubikCube'
    
    public:
    //    cubeSolving(rubikCube cube_) : cube(cube_){}
        cubeSolving() = default;
    
        // Стадии сборки кубика
        void FirstStep(int count = 0, bool isWriteToConsole = true) {
            if (FirstStepCounter++ > 128) {
                // solvingErrors.emplace_back("\nОшибка при сборке кубика номер " + to_string(CubeCounter) + " (1й шаг)\n");
                throw exception();
            }
    
            /*** тут он должен принимать приватные поля кубика, либо обращаться к ним напрямую ***/
            /*** LeftCenter, FrontCenter и т.д - цвета соответствующих центров, а DownPlane, LeftPlane
                 и т.д - плоскости, которые хнанят по 9 мини-кубиков, каждый из которых имеет цвет на каждой из сторон ***/
    
            if (!checkCubeFunctions::isFirstStepCompleted(LeftCenter, FrontCenter, 
    RightCenter, BackCenter, DownCenter, DownPlane, LeftPlane, RightPlane, FrontPlane, BackPlane)) {
    ...


    Соответственно, вот, что я имею
    1) То, что я подключаю к cube.h
    2) Структура кубика
    3) То, что у меня в "solution"

    В последнем я подписал, что хотелось бы хранить в приватном поле solution сам элемент класса кубик, чтобы я мог обращаться так к его полям, но при любом упоминании класса rubikCube у меня вылезают ошибки с надписью "Can't resolve type 'rubikCube'"

    P.S проверку инвариантов шагов решения я уже засунул в "solution"
    P.S.S Plane объявлена внутри cube.h, но после объявления заголовочных файлов, поэтому внутри solution.h я его переопределяю (это нехорошо, но сейчас проблема не в этом)
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @lipa44 Автор вопроса
    Adamos, да, мне не нужны цвета всех сторон кубика, мне нужны только те цвета, которые я переворачиваю, и я использую для этого плоскости, являющиеся векторами, в которых хранятся «мини-кубики», у меня другая архитектура кода, не таблица 5х5, и код (относительно большой) уже написан с использованием ООП, мой вопрос не о том, как оптимальнее решать кубик и как хранить его состояния, а о том, как правильнее использовать ООП, так как в этом и есть суть задания, именно применение ООП для решения задачи, и я хочу понять, как мне правильнее это реализовать
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @lipa44 Автор вопроса
    Это намёк на то, чтобы я прописал геттеры и сеттеры или как мне реализовать данное обращение?

    Потому что есть мнение, что геттеры и сеттеры также противоречат одному из принципов ООП, а именно, инкапсуляции.

    Был бы очень признателен, если бы вы дали идею того, как это реализовать.
  • Как правильно выстроить логику кода с соблюдением принципов ООП?

    @lipa44 Автор вопроса
    Евгений Шатунов, я неправильно выразился по поводу того, что класс должен видеть заголовочные файлы. Я имел ввиду, что я не могу сделать экспорт модуля, как, например, в js, и спокойно использовать элемент класса кубик в другом заголовочном файле.
    Я подключил к заголовочному файлу другой заголовочные файл, который называется «решение кубика», но после попытки объявить элемент класса кубик в этом заголовочном файле или принять в качестве параметра функции, мне среда разработки говорит (can’t resolve type “rubikCube”), хотя я просто создаю/принимаю переменную того типа, которая у меня прописана в заголовочном файле, который я подключил.

    Почему класс кубика должен иметь родителя? Этого я не говорил, это как раз и была часть моего вопроса, имеет ли это смысл, потому что я не совсем понимаю, правильно ли делать классы поворотов, алгоритмов и всего остального наследованными от кубика.

    Что касается поворота, у меня это и есть функция, которую я хотел вынести в отдельный класс, но, опять же, для того, чтобы это работало, единственное, что я могу написать - это то, чтобы функция поворота принимала n-ное количество «обезличенных и отделенных» от кубика параметров, а именно, векторов по ссылкам, и менять в них значения, вместо того, чтобы не принимать никаких параметров, как это было тогда, когда повороты были внутри класса кубика, и могли взаимодействовать с его приватными полями.

    Вопрос как раз и состоит в том, какую структуру, порядок наследования и тому подобное выбрать для данной проблемы, сам я на этот вопрос ответить не могу, поэтому и спрашиваю тут :)