Несоответствие в моем дизайне C ++ - PullRequest
2 голосов
/ 02 февраля 2012

Я сейчас играю в судоку на с ++.Для этого я определил много классов, включая class Pos для позиции и class Error для поддержки ошибок.

Теперь в class Pos,

class Pos {
    int x;
    int y;
public:
    Pos();
    Pos(Pos const&);
    Pos(int,int);

    void    setPos(int,int);

    void    setx(int);
    void    sety(int);

    int    getx() const ;
    int    gety() const ;

    string getPosReport();

    virtual ~Pos();

}; 

Что ясделал: Я ограничил значение x и y, чтобы оно лежало между 0-9, написав setx и sety как,

void Pos::setx(int x){
    if((x < 0) & (x > 9))
        throw  Exception("Invalid Position");
    else
        this->x = x;
}

void Pos::sety(int y){
    if((y < 0) & (y > 9)){
        throw Exception("Invalid Position");
    }
    else
        this->y = y;
}

Моя проблема: Как Pos() должен быть определен.

То, что я работал:

  1. Удаление конструктора по умолчанию, не помогло мне, потому что,

    class Error {
        string errmsg;    
        Pos pos1,pos2; // Pos() must be called!! default constructor cannot be removed!
        bool isError;
        // ...... 
    }
    
  2. Я могу инициализировать x и y в -1 в Pos(), но я чувствую, что это приведет к нестабильности в моем коде.

  3. Я могу иметь int* x и int* yв class Pos такое, что у меня может быть x = y = NULL, но я чувствую, что указатели сделают мой код относительно сложным, чем сейчас.

    так что будет лучше, если кто-нибудь даст решение, стимулирующее сценарийкак х = у = н / д (не применимо)

Ответы [ 4 ]

4 голосов
/ 02 февраля 2012

Дайте Error только конструкторам, которые инициализируют Pos объекты-члены. Тогда вам не нужно нигде по умолчанию конструировать Pos.

Инициализация членов выполняется с помощью «списка инициализации членов», который вы можете найти после двоеточия (:) ниже.

class Error {
   Pos p;

   public:
     Error() : p(1,2) {};
};

Это должно быть описано в вашей книге .


  • Высший балл за правильное определение действительных решений и причины, по которым они не принимаются.
2 голосов
/ 02 февраля 2012

Вы также можете использовать boost :: option в вашем классе Pos. Это общий способ делать «нули» в C ++.

Я не говорю, что это действительно лучший вариант здесь. Если вы действительно не хотите «неинициализированного» состояния, я бы просто использовал {0,0} в качестве позиции «по умолчанию».

0 голосов
/ 02 февраля 2012

Ну, для начала, когда я реализовал судоку, я просто использовал int (в диапазон [0, 81)) для позиции. Но ...

Это класс с семантикой значений, так что вы, вероятно, хотите какой-то конструктора по умолчанию. Есть два правильных подхода к этому:

  • Вы можете просто выбрать произвольную позицию (например, 0, 0) и использовать этот. В этом случае вы можете просто предоставить соответствующие значения по умолчанию для Pos(int, int), и пусть он служит конструктором по умолчанию Что ж. Или:

  • Вы можете использовать дозорные значения (-1 будет хорошим выбором здесь, но подойдет любое значение вне диапазона). В этом случае вы проверяете значения для любого доступа на чтение (кроме копирования), и прервать, если кто-то пытается использовать неправильно инициализированный экземпляр.

(И вы хотите прервать в случае ошибки, а не выдавать исключение.)

0 голосов
/ 02 февраля 2012

Вам нужно удалить конструктор по умолчанию и заставить пользователей вашего класса использовать

Pos(int, int)

версия конструктора, или вам нужно инициализировать x и y чем-то вроде -1 и убедиться, что вы проверяете там значения при их использовании.

Вопрос, который нужно задать, имеет ли смысл создавать ошибочную позицию? Если нет, то удалите конструктор по умолчанию и заставьте ваш объект быть действительным при построении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...