Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.07.2012, 19:40   #1
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
Вопрос Комбинирование классов между собой

Салют!
Собст-но, 2 вопроса:
Первый вопрос: почему в следующем коде первый случай работает, а второй не компилируется?

Первый:
Код:
struct ObjectsTable {
	BaseOf_Unit**		UnitTable;

	ObjectsTable& operator=(const ObjectsTable& tabl);
};

class BaseOf_Unit {
protected:
	ObjectsTable Table; 

public:
	BaseOf_Unit();
	~BaseOf_Unit();
        virtual void Destroy() = 0;
};

class Unit: public BaseOf_Unit {
public:
	Unit();
	~Unit();
	void Destroy();
};
Второй:
Код:
class BaseOf_Unit {
protected:
	ObjectsTable Table; 

public:
	BaseOf_Unit();
	~BaseOf_Unit();
        virtual void Destroy() = 0;
};

class Unit: public BaseOf_Unit {
public:
	Unit();
	~Unit();
	void Destroy();
};

struct ObjectsTable {
	BaseOf_Unit**		UnitTable;

	ObjectsTable& operator=(const ObjectsTable& tabl);
};
В чем загвоздка?Ведь в первом случае неизвестен класс BlockOf_Unit, который использ. в классе ObjectsTable, во втором - наоборот...Но почему такой результат?

И второй вопрос:
Можно ли как нибудь в С++ сделать объявление класса в одном файле(без описания его параметров), мол, такой класс есть, и можно использовать, а описать его реализацию в другом файле?
monolit111 вне форума Ответить с цитированием
Старый 29.07.2012, 19:54   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от monolit111 Посмотреть сообщение
Собст-но, 2 вопроса:
Первый вопрос: почему в следующем коде первый случай работает, а второй не компилируется?

В чем загвоздка?Ведь в первом случае неизвестен класс BlockOf_Unit, который использ. в классе ObjectsTable, во втором - наоборот...Но почему такой результат?

И второй вопрос:
Можно ли как нибудь в С++ сделать объявление класса в одном файле(без описания его параметров), мол, такой класс есть, и можно использовать, а описать его реализацию в другом файле?
В первом случае отсутствует декларация BlockOf_Unit
Во втором случае так же отсутствует декларация BlockOf_Unit.

Можно предположить, что отсутствие декларации BlockOf_Unit не влияет на способность кода быть скомпилированным.


В первом случае используется указатель:
Код:
BaseOf_Unit**		UnitTable;
Во втором случае объект по значению:
Код:
ObjectsTable Table;
Можно предположить, что где то выше по коду присутствует предварительное объявление класса BaseOf_Unit
Если предположение верно - ошибка компиляции во втором случае: "попытка использовать неполный тип", либо: "неизвестный тип" (что более вероятно. Ибо судя по сабжу, вы не знакомы с предварительным объявлением типов)

Так как, вы не соизволили предоставить точный текст ошибки компилятора, а телепаты в отпуске - нельзя утверждать что либо более конкретное.


Ответ на второй вопрос: Нет. Нельзя.
Можно использовать предварительное объявление класса, и использовать указатели/ссылки на этот класс.

Использовать неполный тип данных там, где компилятору критично знать его размер (а значит - строение класса) нельзя.

/зы есть понятия "предварительное объявление класса", "объявление класса", "реализация класса". Это - три разных понятия.

1. Сообщаем компилятору, что такой класс есть:

Код:
class Some; //строение класса не известно. Просто сообщаем, что такой класс существует. И будет объявлен где то ниже.
2. Объявление класса:

Код:
class Some  //объявили строение класса
{
  Some();  //но реализация не известна. 
};
3. Определение класса, тобишь определение его реализации:


Код:
class Some  //объявили строение класса
{
  Some() {};  //определили реализацию
};
Предварительно объявленные классы можно использовать в качестве параметров шаблонов. Так же, можно объявлять указатели/ссылки на объекты таких классов.

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

Объявленные и реализованные можно эксплуатировать на всю катушку.

Последний раз редактировалось _Bers; 29.07.2012 в 20:08.
_Bers вне форума Ответить с цитированием
Старый 29.07.2012, 20:08   #3
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
По умолчанию

КУонеяно же, у меня в конце опечатка.
Не BlockOf_Unit, а BaseOf_Unit, суд по приведенному коду.
Цитата:
Можно предположить, что отсутствие декларации BlockOf_Unit не влияет на способность кода быть скомпилированным.
ну эт я уже понял, вот и спрашиваю, почему)
Цитата:
Можно предположить, что где то выше по коду присутствует предварительное объявление класса BaseOf_Unit
-не, не помню, чтоб в том же файле предварительно его объявлял(да и негде, это начало...)

Да, с ошибками я оплошал...Вот:
Код:
1>  block_of_objects.cpp
1>d:\с++\opengl examples\проэкт\проэкт\object.h(19): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "Table"
1>d:\с++\opengl examples\проэкт\проэкт\object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>d:\с++\opengl examples\проэкт\проэкт other world opengl\object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>d:\с++\opengl examples\проэкт\проэкт\block_of_objects.cpp(28): error C2039: Table: не является членом "BaseOf_Unit"
1>          d:\с++\opengl examples\проэкт\проэкт\object.h(14): см. объявление "BaseOf_Unit"
1>  Создание кода...
1>  Компиляция...
1>  main.cpp
1>d:\с++\opengl examples\проэкт\проэкт\object.h(19): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "Table"
1>d:\с++\opengl examples\проэкт \проэкт\object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>d:\с++\opengl examples\проэкт\проэкт\object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>  Создание кода...
1>  Компиляция...
1>  object.cpp
1>d:\с++\opengl examples\проэкт \проэкт \object.h(19): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "Table"
1>d:\с++\opengl examples\проэкт\проэкт \object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>d:\с++\opengl examples\проэкт \проэкт \object.h(19): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>  Создание кода...
1>  Пропуск... (изменения не обнаружены)
1>СБОЙ построения.
1>
1>Затраченное время: 00:00:10.64
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========
Кстати, может, это ка-то связано с виртуальностью класса BaseOf_Unit?
monolit111 вне форума Ответить с цитированием
Старый 29.07.2012, 20:11   #4
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

во втором случае - создание мембера класса, тип которого ещё не известен.
_Bers вне форума Ответить с цитированием
Старый 29.07.2012, 20:19   #5
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
По умолчанию

почему ж тогда первое прокатывает, интересно..
monolit111 вне форума Ответить с цитированием
Старый 29.07.2012, 20:27   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Предположительно: перед декларацией класса ObjectsTable , существует предварительное объявление класса BaseOf_Unit


Что то вроде:



Код:

class BaseOf_Unit; //где то вверху

...

struct ObjectsTable {
	BaseOf_Unit**		UnitTable;
_Bers вне форума Ответить с цитированием
Старый 29.07.2012, 20:51   #7
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
По умолчанию

Цитата:
Можно предположить, что где то выше по коду присутствует предварительное объявление класса BaseOf_Unit
- это исключено.
monolit111 вне форума Ответить с цитированием
Старый 29.07.2012, 20:54   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

посмотри на пример:

http://liveworkspace.org/code/ef5619...8198332cc0cfd3

Обрати внимание на ошибку компиляции.
Если же расскомментировать предварительное объявление, то код скомпилируется.
Если закомментировать - будет ошибка компиляции

В твоём первом случае код компилируется только и только потому, что компилятору известно о существовании типа данных BaseOf_Unit

Последний раз редактировалось _Bers; 29.07.2012 в 21:05.
_Bers вне форума Ответить с цитированием
Старый 29.07.2012, 22:10   #9
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
По умолчанию

Хочу заметить, что предварительное объявление во втором случае не помогает, а в первом не играет роли....
monolit111 вне форума Ответить с цитированием
Старый 29.07.2012, 23:39   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от monolit111 Посмотреть сообщение
Хочу заметить, что предварительное объявление во втором случае не помогает, а в первом не играет роли....
Разумеется. Во втором случае ты пытаешься использовать тип по значению. Для этого компилятору нужно знать устройство класса. Предварительное объявление не содержит такой информации.

В первом случае, где то выше по коду ты либо объявляешь предварительное объявление BaseOf_Unit , либо цепляешь его туловище целиком
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как связать данные столбцов между собой Алексндр Microsoft Office Excel 4 17.07.2012 09:36
Подключение двух коммутаторов между собой?? Makaveli1986 Помощь студентам 2 21.11.2011 09:45
связь пользователей между собой на сайте строгийЁЖ PHP 5 05.08.2011 11:22
связать несколько компонентов dblookupcomboboxeh между собой. D.O.G БД в Delphi 0 20.08.2010 14:27