Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Инициализация свойств объекта


Автор: Гость_Alexey 13.3.2005, 19:33
Сразу: пишу в VC++ 6. В общем есть некоторый класс (таблица) и в нем заданы некоторые свойства, ну допустим:
Код

class table {

    // parameters
    ROW* DB;
    ROW temp;
        int sz;
        ///
        /// Куча разных методов...
        ///
public:
    table(int count);
    ~table();
} TABLE;

ROW здесь это за-typedef-енный тип структуры (строка таблицы), содержащей определенные поля (скажем, для простоты, что все поля int-овые). В конструкторе объекта создается массив строк таблицы в количестве count. После создания объекта при инициализации полей (в контрукторе обращаюсь к полям через this->DB[индекс].поле и делаю присваивание) выдается Access violation. Чертовщина какая-то... Как бы его отследить и выловить?

ЗЫ - сразу извиняюсь, если вопрос покажется ламерским, потому что я только начинаю прогать в области ООП smile

Автор: bel_nikita 13.3.2005, 20:59
Хотелось бы увидеть сам конструктор

Автор: Гость_Alexey 14.3.2005, 05:15
Да, пожалуйста.
Код

table::table(int count) {
    this->sz=count;  // этот параметр содержит количество строк
    ROW* DB = new ROW [this->sz];
    this->init();  // здесь вызывается инициализация
}

Инициализация:
Код

void table::init() {
    int m;
    for(m=0; m<this->sz; m++) {
        this->DB[m].key=0;
        this->DB[m].id=m;
        this->DB[m].index=0;
        this->DB[m].ret.tm_hour=0;
        this->DB[m].ret.tm_isdst=0;
        this->DB[m].ret.tm_mday=0;
        this->DB[m].ret.tm_min=0;
        this->DB[m].ret.tm_mon=0;
        this->DB[m].ret.tm_sec=0;
        this->DB[m].ret.tm_wday=0;
        this->DB[m].ret.tm_yday=0;
        this->DB[m].ret.tm_year=0;
        *(this->DB[m].book)=0;
        *(this->DB[m].name)=0;
        *(this->DB[m].secn)=0;
        *(this->DB[m].surn)=0;
    }
}

Полагаю, тогда и структуры придется расписать для наглядности.
Код

    typedef struct date {
        int tm_sec;  
        int tm_min;   
        int tm_hour;  
        int tm_mday; 
        int tm_mon;    
        int tm_year;   
        int tm_wday;   
        int tm_yday;   
        int tm_isdst;   
    } DATE;

    typedef struct row {
    int key; // keynum
    char surn[80]; // surname
    char name[80]; // name
    char secn[80]; // secname
    int id; // ticketid
    char book[80]; // book
    int index; // index
    DATE ret; // date
    } ROW;

Автор: Да гость я... 14.3.2005, 06:23
Сразу скажу, что только бегло просмотрел код. Ряд тривиальных рекомендаций:

1) Нет необходимости явно использовать this. Компайлер за Вас сам это сделает.
2) Вместо struct date я бы использовал тип time_t (что есть просто typedef unsigned long time_t). Во-первых, в 9 раз меньше места занимает, чем у Вас, а во-вторых, имеется полный набор CRT ф-ций для манипуляции с данными этого типа. Если уж так хочется, то можно написать класс-обертку, методы к-рого позволяют а) проиницилизировать переменную time_t и б) получить все нужные вам значения как-то year, month, date etc. Реализация может быть примерно такой:

Код

class CWTime // W - for wrapper 
{
  time_t  m_time;
public:
  CWTime() 
  {
      m_time= time(0); // текущее сист. время
  }
  
  int Year   () { return (GetLocalTm()->tm_year + 1900);  }
  int Month() { return (GetLocalTm()->tm_mon + 1);  }
  int Day   (); 
  . . . 
  bool IsDst(); 

private:
  // хэлпер-метод
   tm * GetLocalTm() { return localtime( &m_time);  }
};


Хотя есть ещё более простое решение: в БД хранить time_t, а для вместо указанного выше CWTime - использовать MFС/ATL класс - CTime. Для VC6 это класс MFC, а для VC7 - ещё и ATL. Один из конструкторов CTime принимает time_t, а набор его методов более, чем достаточный.

ЗЫ: по поводу классов для работы с БД, почему Вам CDaoRecordset не подходит?

Автор: Да гость я... 14.3.2005, 06:45
Ну, просмотрел код

Код

class table {

    ROW* DB; // это атрибут класса
 . . .
};

table::table(int count) 
{
    this->sz=count; 
    ROW* DB = new ROW [this->sz]; // А это локальная переменная, маскирующая атрибут
. . .
}

Итак, атрибут класса ROW* DB так и остался неинициализированным.

ЗЫ: хоть и ругают венгерскую нотацию, но я лично "m_" для членов класса всегда юзаю. И мне не нравятся более новомодные варианты обозначений вроде atribute_ или _atribute.

Автор: Гость_Alexey 14.3.2005, 12:09
Спасибки, кажется до меня таки дошло в чем дело =) Жалко что мы гости, так бы авторитет поднял =)
Цитата
по поводу классов для работы с БД, почему Вам CDaoRecordset не подходит?

Потому что это задание для универа. Сначала пишем управление строками, таблицами, потом выше и выше по иерархии. Если бы не надо было это ручками писать, конечно бы запользовал готовый класс.

Автор: Гость_Alexey 14.3.2005, 12:22
Браво! Все заработало, стоило только заменить в конструкторе
Код

ROW* DB = new ROW [this->sz];

на
Код

this->DB = new ROW [this->sz];

smile

Автор: Guest 14.3.2005, 23:39
Гость_Alexey
Все-таки полезно юзать "m_" для имен членов класса - описка сразу была бы заметна.

Цитата
Жалко что мы гости, так бы авторитет поднял =)

Придется зарегистрироваться... smile

Автор: Vyacheslav 3.6.2005, 13:03
Цитата
ЗЫ: хоть и ругают венгерскую нотацию, но я лично "m_" для членов класса всегда юзаю. И мне не нравятся более новомодные варианты обозначений вроде atribute_ или _atribute.

А разве m_ относится к венгерская нотации? Это просто соглашения, принятые MS

Автор: Любитель 7.6.2005, 01:19
Относятся. Просто мелкософт принял венгрескую нотацию. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)