Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Ошибка переопределения методов класса  (Прочитано 12784 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
Sands
Помогающий

ua
Offline Offline

« : 14-02-2008 20:59 » 

Доброго всем времени суток!
Вот какая проблема у меня возникла:
Есть у меня несколько классов(пусть С1 и С2), обьявление и реализация которых полностью содержатся в .h-файлах. Весь код для защиты от повторного включения обрамлен в #ifndef-#endif. Есть дополнительный h-файл (назовем его для простоты AllIncluded.h) в который все они подключаются.
Так вот если создать другой проект, в нем добавить, к примеру, 2 класса A и B (с файлами A.h,A.cpp и B.h B.cpp соответственно), а потм в фалы A.h и B.h включить файл AllIncluded.h то компиляция проходит нормально, а при линковке возникает ошибка переопределения методов классов С1 и С2.
Может ктото в своей практике встречался с подобными проблемами и знает как их побороть? Буду премного благодарен.
Сразу скажу, что #pragma once положение не спасает никоим образом.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 14-02-2008 21:24 » 

А если включать не в *.h, а в *.cpp-файлы? Ещё как вариант - использовать прекомпиляцию заголовков и все "разделяемые" заголовки включать туда. Сейчас наскидку сложно сказать, как именно, но классы, реализованные целиком в заголовках, без проблем в проекты включались, как для VS, так и для GCC.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 14-02-2008 21:49 » 

Sands, дается, что в ты в заголовки включил не только определения классов C1 и C2, но и сам код методов...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sands
Помогающий

ua
Offline Offline

« Ответ #3 : 14-02-2008 22:07 » 

RXL, Так и есть. Я ето и имел ввиду, когда писал, что в хедере "обьявление и реализация"
Вад, К сожалению надо включать в хедеры, потому как при обьявлении классов А и В нужен код из хедеров
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 14-02-2008 22:27 » 

Ну, раз уж такой компактный класс, что в хедере весь как на ладони - то не отделять же реализацию от объявления Улыбаюсь Вообще, если методы определены внутри объявления класса - разве должны быть проблемы?
Записан
Sands
Помогающий

ua
Offline Offline

« Ответ #5 : 14-02-2008 22:44 » 

Тогда возможно я неправильно  прописал реализацию методов?
сейчас у меня обьявление и реализация идут в виде
class C1
{
 void metod1();
 void metod2();
};

void C1::metod1()
{
 ...
}
void C1::metod2()
{
 ...
}

А может стоит написать так

class C1
{
 void metod1()
  {
   ...
  }
 void metod2()
  {
   ...
  }
};

?
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 14-02-2008 22:50 » 

Протестировал: если включать класс, полностью определённый в своём объявлении, то всё нормально компилируется с множественным включением заголовка из разных единиц компиляции. Если есть внешние определения (члены или методы класса, функции, и т.п.), то ошибка "LNK1169: one or more multiply defined symbols found" - что, вообще-то, логично.
Остаётся вопрос: если есть компактный класс и к нему несколько "внешних" операторов (как в теме https://forum.shelek.ru/index.php/topic,14070.0.html), то другого выхода для компиляции, кроме выноса операторов и т.п. в .cpp-файл, нет?

Sands, да, насколько понимаю, так должно работать

P.S. STL помог найти ответ на вопрос: если методы и операторы идут как inline, то это решает проблему линковки.
« Последнее редактирование: 14-02-2008 22:58 от Вад » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 15-02-2008 05:57 » 

P.S. STL помог найти ответ на вопрос: если методы и операторы идут как inline, то это решает проблему линковки.
Это эквивалентно определению метода внутри объявления класса.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 15-02-2008 06:28 » new

Так и есть. Это я что-то растерялся в отношении операторов и т.п. Вот выдержка из ISO-стандарта на C++, которая и является ответом на вопрос, можно ли в заголовках использовать определения методов, а потом включать в разные единицы компиляции:

Цитата: ISO/IEC 14882:2003 раздел 3.2
Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required.

А это - подтверждение слов dimka:
Цитата: ISO/IEC 14882:2003 раздел 9.3
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2)
« Последнее редактирование: 15-02-2008 06:31 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines