Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> расположение данных в наследуемом классе, хочу скопировать все наследованное 
:(
    Опции темы
DENNN
  Дата 8.10.2003, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Код

class CGeoObj
{
public:
LONG m_id;
LONG m_type_id;
TCHAR m_name[251];
double m_lat;
double m_lon;
TCHAR m_desc[251];

CGeoObj(){memset(this,0,sizeof(this));}
};

class CGeoObjDBAccessor : public CGeoObj
{
public:

// The following wizard-generated data members contain status
// values for the corresponding fields in the column map. You
// can use these values to hold NULL values that the database
// returns or to hold error information when the compiler returns
// errors. See Field Status Data Members in Wizard-Generated
// Accessors in the Visual C++ documentation for more information
// on using these fields.
// NOTE: You must initialize these fields before setting/inserting data!

DBSTATUS m_dwidStatus;
DBSTATUS m_dwtype_idStatus;
DBSTATUS m_dwnameStatus;
DBSTATUS m_dwlatStatus;
DBSTATUS m_dwlonStatus;
DBSTATUS m_dwdescStatus;

// The following wizard-generated data members contain length
// values for the corresponding fields in the column map.
// NOTE: For variable-length columns, you must initialize these
//       fields before setting/inserting data!

DBLENGTH m_dwidLength;
DBLENGTH m_dwtype_idLength;
DBLENGTH m_dwnameLength;
DBLENGTH m_dwlatLength;
DBLENGTH m_dwlonLength;
DBLENGTH m_dwdescLength;


void GetRowsetProperties(CDBPropSet* pPropSet)
{
 pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
 pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
}

HRESULT OpenDataSource(LPCTSTR host, LPCTSTR initialcatalog, LPCTSTR login, LPCTSTR password)
{
 CDataSource _db;
 HRESULT hr;

 gethostname(localhost,(int) sizeof(localhost));
 CString str;
 str.Format("Provider=SQLOLEDB.1;Persist Security Info=False;User ID=%s;PWD=%s;Initial Catalog=%s;Data Source=%s;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=%s;Use Encryption for Data=False;Tag with column collation when possible=False",login,password,initialcatalog,host,localhost);
 USES_CONVERSION;
 hr = _db.OpenFromInitializationString( A2COLE(str));
 if (FAILED(hr))
 {
#ifdef _DEBUG
  AtlTraceErrorRecords(hr);
#endif
  return hr;
 }
 return m_session.Open(_db);
}

void CloseDataSource()
{
 m_session.Close();
}

operator const CSession&()
{
 return m_session;
}

CSession m_session;

BEGIN_COLUMN_MAP(CGeoObjDBAccessor)
 COLUMN_ENTRY_LENGTH_STATUS(1, m_id, m_dwidLength, m_dwidStatus)
 COLUMN_ENTRY_LENGTH_STATUS(2, m_type_id, m_dwtype_idLength, m_dwtype_idStatus)
 COLUMN_ENTRY_LENGTH_STATUS(3, m_name, m_dwnameLength, m_dwnameStatus)
 COLUMN_ENTRY_LENGTH_STATUS(4, m_lat, m_dwlatLength, m_dwlatStatus)
 COLUMN_ENTRY_LENGTH_STATUS(5, m_lon, m_dwlonLength, m_dwlonStatus)
 COLUMN_ENTRY_LENGTH_STATUS(6, m_desc, m_dwdescLength, m_dwdescStatus)
END_COLUMN_MAP()
};

Сорри, если код большой но так проблема полностью ясна.

У меня пробел в образовании sad.gif. Есть кусок кода:
Код

CGeoObj a;
CGeoObjDBAccessor b;
////здесь мы после некоторых манипуляций получили в b данные
// хочу получить их копию в переменной a (чтоб положить в контейнер только эти данные)
memcpy (&a, &b, sizeof(CGeoObj ));
не срабатывает - очевидно смещение данных изменилось.
Можно конечно ввести перпеменные-флаги вначале и в конце блока данных, но отсчитывать смещения таким образом не очень изящно. Есть способ проще?

Это сообщение отредактировал(а) DENNN - 8.10.2003, 15:30
PM ICQ   Вверх
setq
Дата 8.10.2003, 15:57 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











а наследование обязательно?
может можно обойтись
Код
class SMTH {};
class SOME_MORE {SMTH s;};

и определением метода копирования в SOME_MORE.
кажется, проблемма бы решилась...

код весь не читал. может я не прав.
  Вверх
DENNN
Дата 8.10.2003, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Мастер генерит аксессор для доступа к БД через OLE DB. Я вынес сами данные в отдельный класс-родител, чтоб разделить функциональность самих данных и методов их получения через COM. Макрос привязки (BEGIN_COLUMN_MAP) 100% работает нормально когда данные являются непосредственно членами класса. Изменить таким образом определение класса значит нажить возможные проблемы если не сейчас то в будущем при переходе на очередную версию студии. Поэтому желательно сделать именно так sad.gif
PM ICQ   Вверх
RAN
Дата 8.10.2003, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Вообще, это может привести к проблемам в будущем. Вдруг в других компиляторах работать не будет.
А так попробуй привести к одному типу:
memcpy (&a, (CGeoObj*)(&b), sizeof(CGeoObj ));

PM MAIL ICQ   Вверх
DENNN
Дата 9.10.2003, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Мдя, похоже надежней ввести две пустые переменные до начала данных и после них. Тогда memcpy выглядит так (для переменных token1 и token2):
memcpy( (void*)&a.token1, (void*)&b.token1, (size_t)((LPBYTE)&a.token2-(LPBYTE)&a.token1) );
PM ICQ   Вверх
RAN
Дата 9.10.2003, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Не понял, а мой вариант не катит что-ли?
PM MAIL ICQ   Вверх
DENNN
Дата 9.10.2003, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Цитата
Не понял, а мой вариант не катит что-ли?

А это кто сказал?
Цитата
Вообще, это может привести к проблемам в будущем. Вдруг в других компиляторах работать не будет.



PM ICQ   Вверх
RAN
Дата 9.10.2003, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



DENNN, всё работает.
Проблема у тебя в том, по-моему, что базовый класс у тебя не содержит виртуальных функций, а наследник, похоже, содержит. Ты их, наверное, просто нам не показал. Я прав?
Если да, то возникает такая ситуация. Класс CGeoObj содержит только данные, а класс CGeoObjDBAccessor в первых 4 байтах содержит указатель на vtable, потом класс CGeoObj, а потом свои данные. Чтоб получить указатель на данные CGeoObj выполни приведение типа для указателя на CGeoObjDBAccessor к указателю на CGeoObj. И компилятор возьмёт то, что нужно.

P.S. Нужно быть осторожным. Если базовый класс содержит виртуальные функции, то будет заменён указатель на vtable. Таким образом базовый класс будет использовать виртуальные функции наследника и скорее всего возникнет ошибка доступа к памяти, когда эти функции будут обращаться к полям класса CGeoObjDBAccessor, на самом деле отсутствующим в CGeoObj. Во как закрутил smile.gif.
PM MAIL ICQ   Вверх
RAN
Дата 9.10.2003, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Цитата

А это кто сказал?

Вообще, это может привести к проблемам в будущем. Вдруг в других компиляторах работать не будет.


Я имел ввиду использование memcpy. По-моему, через оператор = будет работать не намного медленнее.

P.S. Кстати, мой вариант, по идее, должен работать везде. Сам подумай. После приведения к одному типу, указатели будут указывать на данные, хранящиеся в структуре одного вида. Проблема в том, что memcpy копирует не думая. Поэтому и ссылку на vtable скопирует, не задаваясь вопросами наследования, полиморфизма и прочей "лабуды".

PM MAIL ICQ   Вверх
DENNN
Дата 9.10.2003, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Цитата
Проблема у тебя в том, по-моему, что базовый класс у тебя не содержит виртуальных функций, а наследник, похоже, содержит. Ты их, наверное, просто нам не показал. Я прав?

Нет. Это полная копия кода для обеих классов.
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0514 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.