Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Класс не инициализируется

2.0K
20 марта 2003 года
udgine
20 / / 04.03.2003
Нужна помощь. MSVC++.NET.
В файлах Hash.h и Hash.cpp описан шаблон класса CHashTable.
В файле People.h структура CPeopCust.
Проблема следующего содежания: хочу объявить перерменную
типа CHashTable в диалоговом окне (классе диалогового окна)

BankDlg.h:
#pragma once
#include "afxwin.h"
#include "Hash.h"

...

// CBankDlg dialog
class CBankDlg : public CDialog
{

...

public:
...

CHashTable<T> IndexPeop();

...
};

Все вроде ОК...

// BankDlg.cpp : implementation file

#include "stdafx.h"
#include "Bank.h"
#include "BankDlg.h"
#include "People.h"

BOOL CBankDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...инициализирую переменную...
CHashTable<CPeopCust> IndexPeop();
...
}

...
...и тут происходит самое интересное. Компилятор не дает никаких ошибок,
но есть предупреждение:

Compiling...
BankDlg.cpp
c:\Мои документы\Visual Studio Projects\Bank\BankDlg.cpp(107) : warning C4930: 'CHashTable<T> IndexPeop(void)': prototyped function not called (was a variable definition intended?)
with
[
T=CPeopCust
]
Linking...
т.е. конструктор класса не выполнился, соответственно класс не инициализирован.
Вопрос вытекает сам собой, в чем дело?
3
20 марта 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by udgine

public:
...

CHashTable<T> IndexPeop();



Это объявление метода-члена, а не переменной-члена. Правильно будет так:

public:
CHashTable<T> IndexPeop;

Цитата:
Originally posted by udgine

BOOL CBankDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...инициализирую переменную...
CHashTable<CPeopCust> IndexPeop();
...
}



Здесь не инициализация переменной, объявленной в классе, а создание новой локальной переменной.

Конструктор для переменной, объявленной в классе, можно вызвать лишь в конструкторе класса:

CBankDlg::CBankDlg() : IndexPeop()
{
}

Если это не устраивает, объяви в классе CBankDlg указатель на тип CHashTable<T> и создавай объект динамически, где это нужно.

// CBankDlg dialog
class CBankDlg : public CDialog
{
public:
CHashTable<T> *pIndexPeop;
};

BOOL CBankDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...инициализирую переменную...
pIndexPeop = new CHashTable<CPeopCust>();
...
}

2.0K
21 марта 2003 года
udgine
20 / / 04.03.2003
Цитата:
Originally posted by Green

Если это не устраивает, объяви в классе CBankDlg указатель на тип CHashTable<T> и создавай объект динамически, где это нужно.

// CBankDlg dialog
class CBankDlg : public CDialog
{
public:
CHashTable<T> *pIndexPeop;
};

BOOL CBankDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...инициализирую переменную...
pIndexPeop = new CHashTable<CPeopCust>();
...
}


Так и сделал, но лучше не стало:
c:\Мои документы\Visual Studio Projects\Bank\BankDlg.cpp(171) : error C2440: '=' : cannot convert from 'CHashTable<T> *' to 'CHashTable<T> *'
with
[
T=CPeopCust
]
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

3
21 марта 2003 года
Green
4.8K / / 20.01.2000
Очепяточка!

// CBankDlg dialog
class CBankDlg : public CDialog
{
public:
CHashTable<CPeopCust> *pIndexPeop;
};

BOOL CBankDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...инициализирую переменную...
pIndexPeop = new CHashTable<CPeopCust>();
...
}
2.0K
21 марта 2003 года
udgine
20 / / 04.03.2003
Цитата:
Originally posted by Green
Очепяточка!
// CBankDlg dialog
class CBankDlg : public CDialog
{
public:
CHashTable<CPeopCust> *pIndexPeop;
};


:) Спасибо! Вроде прокатило!

2.0K
24 марта 2003 года
udgine
20 / / 04.03.2003
:( Поторопился я!!!
Нифига оказывается не работает. Компилятор во че выдает:

BankDlg.cpp
Linking...
BankDlg.obj : error LNK2019: unresolved external symbol "public: __thiscall CHashTable<struct CPeopCust>::CHashTable<struct CPeopCust>(int)" (??0?$CHashTable@UCPeopCust@@@@QAE@H@Z) referenced in function "protected: virtual int __thiscall CBankDlg::OnInitDialog(void)" (?OnInitDialog@CBankDlg@@MAEHXZ)
Debug/Bank.exe : fatal error LNK1120: 1 unresolved externals

Build log was saved at "file://c:\Мои документы\Visual Studio Projects\Bank\Debug\BuildLog.htm"
Bank - 2 error(s), 0 warning(s)
3
24 марта 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by udgine
:( Поторопился я!!!
Нифига оказывается не работает. Компилятор во че выдает:

BankDlg.cpp
Linking...
BankDlg.obj : error LNK2019: unresolved external symbol "public: __thiscall CHashTable<struct CPeopCust>::CHashTable<struct CPeopCust>(int)" (??0?$CHashTable@UCPeopCust@@@@QAE@H@Z) referenced in function "protected: virtual int __thiscall CBankDlg::OnInitDialog(void)" (?OnInitDialog@CBankDlg@@MAEHXZ)
Debug/Bank.exe : fatal error LNK1120: 1 unresolved externals

Build log was saved at "file://c:\Мои документы\Visual Studio Projects\Bank\Debug\BuildLog.htm"
Bank - 2 error(s), 0 warning(s)



Ошибка заключается в том, что ты вызываешь в CBankDlg::OnInitDialog() конструктор
CHashTable<struct CPeopCust>::CHashTable<struct CPeopCust>(int)
т.е. видимо ты написал

pIndexPeop = new CHashTable<CPeopCust>(какое-то числовое значение);

Вместо

pIndexPeop = new CHashTable<CPeopCust>();

Кстати, можно просто написать:

pIndexPeop = new CHashTable<CPeopCust>;

2.0K
24 марта 2003 года
udgine
20 / / 04.03.2003
Цитата:
Originally posted by Green

т.е. видимо ты написал
pIndexPeop = new CHashTable<CPeopCust>(какое-то числовое значение);



Да так и сделал ...

Цитата:

Вместо

pIndexPeop = new CHashTable<CPeopCust>();

Кстати, можно просто написать:

pIndexPeop = new CHashTable<CPeopCust>;



Пробовал pIndexPeop = new CHashTable<CPeopCust>() и pIndexPeop = new CHashTable<CPeopCust>, одна и та же ошибка:

BankDlg.cpp
c:\Мои документы\Visual Studio Projects\Bank\BankDlg.cpp(173) : error C2512: 'CHashTable<T>' : no appropriate default constructor available
with
[
T=CPeopCust
]

Может посмотришь исходники, я уже 2-ую неделю борюсь с этим?

3
24 марта 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by udgine


Да так и сделал ...



Пробовал pIndexPeop = new CHashTable<CPeopCust>() и pIndexPeop = new CHashTable<CPeopCust>, одна и та же ошибка:

BankDlg.cpp
c:\Мои документы\Visual Studio Projects\Bank\BankDlg.cpp(173) : error C2512: 'CHashTable<T>' : no appropriate default constructor available
with
[
T=CPeopCust
]

Может посмотришь исходники, я уже 2-ую неделю борюсь с этим?



Архив поврежден, видимо, при перекачке. Но из того, что смог открыть, видно, что в Hash.h объявлен конструктор

template<class T>
CHashTable::CHashTable(int nbuckets);

сл-но надо все же ври вызове передовать численное значение.

В Hash.cpp реализация
template<class T>
CHashTable<T>::CHashTable(int nbuckets)

Но шаблонный класс называется то
template<class T> CHashTable,
а не
template<class T> CHashTable<T>

Короче говоря, в Hash.cpp надо написать

template<class T>
CHashTable::CHashTable(int nbuckets)

вместо

template<class T>
CHashTable<T>::CHashTable(int nbuckets)


Кстати в HashTable.h объявлен шаблонный класс template <class T>
class HashTable<T>
Может возникнуть путанница.

2.0K
26 марта 2003 года
udgine
20 / / 04.03.2003
Цитата:
Originally posted by Green

Но шаблонный класс называется то
template<class T> CHashTable,
а не
template<class T> CHashTable<T>

Короче говоря, в Hash.cpp надо написать

template<class T>
CHashTable::CHashTable(int nbuckets)

вместо

template<class T>
CHashTable<T>::CHashTable(int nbuckets)



В том то все и дело, что так:
template<class T>
CHashTable::CHashTable(int nbuckets)
не работает, компилятор говорит, что шаблону нужно указывать в качестве параметра "шаблонный параметр" (небольшой каламбур), ну в общем надо делать так: template<class T>
CHashTable<T>::CHashTable(int nbuckets)
Но и так ничего не работает.
Может если есть время и возможность я скину исходник на мыло, посмотришь, может какие идеи появятся?

3
26 марта 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by udgine


В том то все и дело, что так:
template<class T>
CHashTable::CHashTable(int nbuckets)
не работает, компилятор говорит, что шаблону нужно указывать в качестве параметра "шаблонный параметр" (небольшой каламбур), ну в общем надо делать так: template<class T>
CHashTable<T>::CHashTable(int nbuckets)
Но и так ничего не работает.
Может если есть время и возможность я скину исходник на мыло, посмотришь, может какие идеи появятся?



Блин... Вот мы тормозим. Всё элементарно, Ватсон!
Дело в том, что шаблонный класс не может быть скомпилирован без инстанирования определенным типом. Т.о. при компиляции Hash.cpp не создается соотв. объектного кода, взгляни на Hash.obj, там полный бред. Тоже самое, кстати, и с LinkedList.cpp
Решение: перенести всё из Hash.cpp в Hash.h
Этим, кстати, объясняется, что весь atl/wtl находиться в *.h
И ещё я рекомендую вог все *.h вставлять CodeGuard-ы, т.е. запись в самом начале и в самом конце заголовочного файла, исключающее его повторное включение:

#ifndef _HASH_H_ // В начале файла
#define _HASH_H_ // _HASH_H_ - уникальный макрос
.................
#endif //_HASH_H_ // В конце файла

Имя уникального макроса лично я определяю по названию файла.
Можно конечно воспользоваться #pragma once, но мне как-то не по душе эта M$-фича.

Действительно, правильно писать
template<class T>
CHashTable<T>::CHashTable(int nbuckets)

Незабудь, что в BOOL CBankDlg::OnInitDialog() нужно вызвать конструктор с целочисленным аргументом:
pIndexPeop=new CHashTable<CPeopCust>(777);

2.0K
26 марта 2003 года
udgine
20 / / 04.03.2003
:D Да, да... Я тоже догадался. Ну теперь надеюсь буте все ОК. Большое спасибо за уделенное время!
---------------------------
P.S. Все гениальное просто!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог