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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Явное воплощение шаблонной функции 
V
    Опции темы
Brodyaga
Дата 27.7.2009, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Всей здравствуйте! Хочу сделать у класса одну шаблонную функцию. Делаю так

myclass.h

Код

class MyClass
{
public:
   MyClass();
   ~MyClass();

   template<class T>
   static T* MyFunc(T*);
};


myclass.cpp

Код

MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}

template <class T>
T* MyClass::MyFunc(T* object)
{
 return null;
}


myclassinst.cpp

Код

/*Файл реализующий "модель явного воплощения" для организации кода с шаблонами*/
#include "StdAfx.h"

#include "myclass.cpp"

#include "ClassA.h"
#include "ClassB.h"

//Набор директив явного воплощения
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);


На всё это дело студия ругается так:
Код

Error    113    error LNK2005: "public: __cdecl MyClass::MyClass(void)" (??0MyClass@@QAA@XZ) already defined in myclass.obj                файл - myclassinst.obj
Error    114    error LNK2005: "public: __cdecl MyClass::~MyClass(void)" (??1MyClass@@QAA@XZ) already defined in myclass.obj               файл - myclassinst.obj    

и т.д.

может кто подскажет, что я делаю неправильно?

P.S. MSVC 2005

Это сообщение отредактировал(а) Brodyaga - 27.7.2009, 18:46
PM MAIL   Вверх
triclosan
Дата 27.7.2009, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

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



попробуй не разносить определение и реализацию в разные файлы
PM MAIL   Вверх
Brodyaga
Дата 27.7.2009, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

попробуй не разносить определение и реализацию в разные файлы

Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.
Поэтому мне интересно как всётаки так сделать!?
PM MAIL   Вверх
vinick
Дата 27.7.2009, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 3
Всего: 22



Цитата(Brodyaga @  27.7.2009,  19:13 Найти цитируемый пост)
Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.
Поэтому мне интересно как всётаки так сделать!? 

Вынести реализацию шаблонов в cpp-файл так как ты хочешь можно только при помощи ключевого слова export, которое поддерживают только Comeu С++ и Borland C++, а сейчас эту фичу по-моему вобще исключили из стандарта языка.

Кстати, зачем понадобилось явное инстанцирование?  Я встречал его только в одном старом проекте, где древний gcc  не мог сам разобраться с шаблонами и ему приходилось помогать руками.
PM MAIL ICQ Jabber   Вверх
azesmcar
Дата 27.7.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  27.7.2009,  19:13 Найти цитируемый пост)
Пробовал уже.. так работает.. Но ведь явное воплощение и нужно для того, чтобы работало всё с разносом определения и реализации в разные файлы.

Экспорт шаблонов 99% компиляторов не поддерживается, пиши реализацию в .h файле.

меня опередили

Это сообщение отредактировал(а) azesmcar - 27.7.2009, 19:51
PM   Вверх
Brodyaga
Дата 27.7.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Вынести реализацию шаблонов в cpp-файл так как ты хочешь можно только при помощи ключевого слова export, которое поддерживают только Comeu С++ и Borland C++, а сейчас эту фичу по-моему вобще исключили из стандарта языка.

Не только... Например если я объявляю весь класс шаблонным, а не только функцию, а в файле myclassinst.cpp делаю так:
Код

template MyClass<ClassA>;
template MyClass<ClassB>;

то всё ок!

Цитата

Кстати, зачем понадобилось явное инстанцирование?

Затем, чтобы линкер не ругался на пустые ссылки оставленные компилятором из-за того, что он не может произвести воплощение шаблона.

Цитата

Экспорт шаблонов 99% компиляторов не поддерживается, пиши реализацию в .h файле.

Ну студийным ведь поддерживается? значит им както можно сделать? Ведь если делать целый класс шаблонным, то работает же......
PM MAIL   Вверх
azesmcar
Дата 27.7.2009, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  27.7.2009,  20:29 Найти цитируемый пост)
Ну студийным ведь поддерживается? 

Нет, не поддерживается.

Цитата(Brodyaga @  27.7.2009,  20:29 Найти цитируемый пост)
Ведь если делать целый класс шаблонным, то работает же...... 

Нет, не будет работать, если у тебя что-то работает - покажи, найдем причину, сделаем так что перестанет работать smile 
PM   Вверх
UnrealMan
Дата 27.7.2009, 23:54 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Эх, Brodyaga, не туда ты забрёл smile Тебя тут щас научат, что VC++ не умеет работать с явным инстанцированием и что явное инстанцирование - это вообще экспорт шаблонов smile Ты только слушай да рот пошире разевай. Посмотри лучше на текст ошибки - там же ясно сказано, что проблема с конструктором и деструктором, которые у тебя не шаблонные и не inline, но определяются сразу в двух cpp файлах.
PM MAIL   Вверх
Brodyaga
Дата 28.7.2009, 06:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Цитата

Ведь если делать целый класс шаблонным, то работает же...... 


Нет, не будет работать, если у тебя что-то работает - покажи


Нет, работает!

myclass.h
Код

template<class T>
class MyClass
{
public:
   MyClass();
   ~MyClass();

   static T* MyFunc(T*);
};


myclass.cpp
Код

template <class T>
MyClass<T>::MyClass()
{
}
template <class T>
MyClass<T>::~MyClass()
{
}
template <class T>
T* MyClass<T>::MyFunc(T* object)
{
 return null;
}


myclassinst.cpp
Код

/*Файл реализующий "модель явного воплощения" для организации кода с шаблонами*/
#include "StdAfx.h"
#include "myclass.cpp"
#include "ClassA.h"
#include "ClassB.h"

//Набор директив явного воплощения
template MyClass<ClassA>;
template MyClass<ClassB>;


вот так, РАБОТАЕТ!


Цитата

Эх, Brodyaga, не туда ты забрёл smile Тебя тут щас научат, что VC++ не умеет работать с явным инстанцированием и что явное инстанцирование - это вообще экспорт шаблонов smile Ты только слушай да рот пошире разевай.

да я пока ещё не вижу к чему можно прислушаться  smile

Цитата

Посмотри лучше на текст ошибки - там же ясно сказано, что проблема с конструктором и деструктором, которые у тебя не шаблонные и не inline, но определяются сразу в двух cpp файлах.

Тоесть избежать этого можно только включив строки 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);
в myclass.cpp? Я кстати так тоже пробовал и так работает... но хотелось чтобы эти строки в отдельном файле находились... Значит вариант с отдельным файлом(myclassinst.cpp) для этих строк отпадает? только в myclass.cpp!?!?

Это сообщение отредактировал(а) Brodyaga - 28.7.2009, 06:55
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



UnrealMan

А причем тут явное инстанцирование? Человек писал что хочет реализовывать и определять в разных файлах, если он инстанцировать хочет, так значит термин не тот подобрал. Лично мне слово "воплощение шаблона" ничего не говорит smile Может твои догадки и вернее отражают суть.

Цитата(Brodyaga @  28.7.2009,  06:53 Найти цитируемый пост)
#include "myclass.cpp"

Конечно будет работать, какая разница включать cpp файл или header? В итоге это одно и тоже. Если в конечном итоге определение будет включено в cpp файл - будет работать, дели хоть на 100 файлов.
UnrealMan прав, тут экспортом шаблонов и не пахнет. Я код не смотрел, прочитал 
Цитата

чтобы работало всё с разносом определения и реализации в разные файлы

думал оно и есть.
После этой фразы не удивительно что все подумали про экспорт шаблонов.

Добавлено @ 07:05
Brodyaga

А проблема в том, что ты делаешь include cpp файл и его же скорее всего компилируешь, получаеся два определения конструктора и деструктора, либо пиши все в хидер файле, либо убери свой cpp который инклудишь из проекта, чтоб не компилировался.

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 07:09
PM   Вверх
Леопольд
Дата 28.7.2009, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(azesmcar @ 28.7.2009,  06:56)
А проблема в том, что ты делаешь include cpp файл и его же скорее всего компилируешь, получаеся два определения конструктора и деструктора, либо пиши все в хидер файле...

А ещё лучше, разберись с линковкой С++. Тебе необходимо понимание как она работает.
Надо помнить несколько вещей: что такое "единица трансляции", он же "модуль". Каким образом линковщик работает с разными фукнциями/переменными (static, inline и обычные) когда код оных уже оттранслирован в (разные) модули. Всё это объединаяется под одним термином - "раздельная компиляция".

как правило, сколько файлов *.cpp столько и модулей *.obj, не следует делать #include <*.cpp>

Цитата(azesmcar @ 28.7.2009,  06:56)
либо убери свой cpp который инклудишь из проекта, чтоб не компилировался.

Либо переименуй его в *.h smile


Это сообщение отредактировал(а) Леопольд - 28.7.2009, 08:06


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 28.7.2009, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Я код не смотрел,

А надо смотреть всё smile


Цитата

Цитата

чтобы работало всё с разносом определения и реализации в разные файлы


думал оно и есть.
После этой фразы не удивительно что все подумали про экспорт шаблонов.

Я имел ввиду, что хочу чтобы явное воплощение(инстанцирование) работало и с разносом определения и реализации в разные файлы.. помоему всё было предельно ясно, если читать сначала... 

Цитата

как правило, сколько файлов *.cpp столько и модулей *.obj

это я знаю... 

Цитата

не следует делать #include <*.cpp>

при моём подходе именно cpp нужно инклудить

Цитата

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


Цитата

Либо переименуй его в *.h smile


Чото мне это как то криво кажется... наверное лучше строки 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);
в myclass.cpp перенесу..


PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
А надо смотреть всё smile

Смотря что делаешь, я на конкретную фразу отвечал а не на вопрос. Код смотреть не было времени и причину ошибки я тоже не называл. То что ты хочешь реализуется методом экспорта шаблонов, а твоя реализация отличается от реализации в заголовочном файле лишь тем, что ты .h заменил на .cpp (по сути файл переименовал) и еще компилируешь его.

Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
при моём подходе именно cpp нужно инклудить

какая разница? что меняет расширение файла? Это условности.

Цитата(Brodyaga @  28.7.2009,  08:36 Найти цитируемый пост)
Чото мне это как то криво кажется... наверное лучше строки 

криво это инклудить cpp файл.

Избавь себя от проблем, пиши все в заголовочном файле. В этом ничего ненормального нет, посмотри как сделано в STL.

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 08:46
PM   Вверх
Brodyaga
Дата 28.7.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Смотря что делаешь, я на конкретную фразу отвечал а не на вопрос.

А фраза вытекала из конкретного вопроса, поэтому иговорю что надо всё смотреть smile

Цитата


какая разница? что меняет расширение файла? Это условности.

криво это инклудить cpp файл.

Про расширение какого именно файла вы говорите поясняйте пожалуйста.

Цитата

какая разница? что меняет расширение файла? Это условности.

Такая, что если подключать myclass.h файл к файлу myclassinst.cpp, то явное воплощение шаблона не работает..
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
А фраза вытекала из конкретного вопроса, поэтому иговорю что надо всё смотреть smile

Без разницы из чего она вытекает, фраза была полной и носила конкретный смысл. В правильно сформулированном виде эта фраза однозначна и не зависит от контекста.

Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
Про расширение какого именно файла вы говорите поясняйте пожалуйста.

про расширение cpp файла.

Цитата(Brodyaga @  28.7.2009,  10:26 Найти цитируемый пост)
Такая, что если подключать myclass.h файл к файлу myclassinst.cpp, то явное воплощение шаблона не работает.. 

Повторяюсь, CPP файл твой компилятор КОМПИЛИРУЕТ, потому при линковке у класса получается два конструктора
1 - в myclass.cpp
2 - в myclassinst.cpp
а .h файл компилятор игнорирует и не компилирует.
PM   Вверх
Brodyaga
Дата 28.7.2009, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Без разницы из чего она вытекает, фраза была полной и носила конкретный смысл. В правильно сформулированном виде эта фраза однозначна и не зависит от контекста.

Только если эту фразу рассматривать отдельно то может быть, но так как она была в общем разговоре, то ответ на эту фразу отдельно не имеет никакого значения. Фраза имеет смысл только со всеми предыдущими фразами.

Цитата

про расширение cpp файла.

Повторю вопрос...
Про расширение КАКОГО ИМЕННО файла вы говорите поясняйте пожалуйста?

Цитата

Повторяюсь, CPP файл твой компилятор КОМПИЛИРУЕТ, потому при линковке у класса получается два конструктора
1 - в myclass.cpp
2 - в myclassinst.cpp
а .h файл компилятор игнорирует и не компилирует.

я всё ПРЕКРАСНО понимаю. Объясните что конкретно вы предлагаете сделать и понятнее.(Если есть предложения кроме как размещать всё в h файле). Под ПОНЯТНЕЕ я имею ввиду привести ИМЯ файла в котором нужно поменять расширение или инклуд(если второе, то на какой инклуд).
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  10:51 Найти цитируемый пост)
Только если эту фразу рассматривать отдельно то может быть, но так как она была в общем разговоре, то ответ на эту фразу отдельно не имеет никакого значения. Фраза имеет смысл только со всеми предыдущими фразами.

Совершенно неохота спорить. Твое желание правильно реализуется с помощью экспорта шаблонов, о котором я и написал. Не нравиться ответ - игнорируй. В мои обязанности не входит предоставление 100% точной информации. Отвечаю насколько позволяет время по собственному желанию.

Цитата(Brodyaga @  28.7.2009,  10:51 Найти цитируемый пост)
Про расширение КАКОГО ИМЕННО файла вы говорите поясняйте пожалуйста?

про расширение myclass.cpp, cpp файла который ты инклудишь и компилируешь.

Цитата(Brodyaga @  28.7.2009,  10:51 Найти цитируемый пост)
я всё ПРЕКРАСНО понимаю. Объясните что конкретно вы предлагаете сделать и понятнее.

 smile я что так непонятно выражаюсь?
1. Я предлагаю писать шаблонные функции в заголовочном файле (это я рекомендую, это не криво. Так написан весь STL)
2. Если не хочешь - я предлагаю сменить расширение своего файла (myclass.cpp) на myclass.h например или убери его из проекта вообще, чтобы не компилировался. (правый клик мышки на файле в solution explorer, rename/delete).
PM   Вверх
Brodyaga
Дата 28.7.2009, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Совершенно неохота спорить. Твое желание правильно реализуется с помощью экспорта шаблонов, о котором я и написал. 

дык какой мне смысл от ответа на одну фразу из всего разговора, которая сама по себе отдельно для меня не интересна?
Цитата

В мои обязанности не входит предоставление 100% точной информации.

я и не говорю что ты обязан.
Ладно.. замяли, действительно бесполезный спор.

Цитата

про расширение myclass.cpp, cpp файла который ты инклудишь и компилируешь.

вот теперь ясно что про myclass а не myclassinst.

Цитата

я что так непонятно выражаюсь?

Сейчас , после того как пояснил нормально всё понятно.

Итоги:
Цитата

1. Я предлагаю писать шаблонные функции в заголовочном файле (это я рекомендую, это не криво. Так написан весь STL)

Этот вариант рабочий, но мне почему то не нравится. Ессно я сделаю так если по другому не получится.

Цитата

2. Если не хочешь - я предлагаю сменить расширение своего файла (myclass.cpp) на myclass.h

Если ты имеешь ввиду в файле myclassinst сменить инклуд myclass.cpp на myclass.h, то я говорю, что так работать не будет. Студия ругается на то что шаблон явно не инстанцирован.

Цитата

или убери его из проекта вообще, чтобы не компилировался.

Так работает тоже. но так уж точно както криво.


А как вы относитесь к варианту добавить строки 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);
в файл myclass.cpp ?
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  12:30 Найти цитируемый пост)
Этот вариант рабочий, но мне почему то не нравится. Ессно я сделаю так если по другому не получится.

Очень зря, это вполне нормально.

Цитата(Brodyaga @  28.7.2009,  12:30 Найти цитируемый пост)
Если ты имеешь ввиду в файле myclassinst сменить инклуд myclass.cpp на myclass.h, то я говорю, что так работать не будет. Студия ругается на то что шаблон явно не инстанцирован.

Не совсем понял о чем речь.

Цитата(Brodyaga @  28.7.2009,  12:30 Найти цитируемый пост)
Так работает тоже. но так уж точно както криво.

Конечно криво. Смотри.
Что делает include? ничего особенного, просто берет содержимое одного файла и копирует в другой (грубо говоря). Т.е. вместо
#include "myclass.cpp"
у тебя будет содержимое файла myclass.cpp и дальше какие-то строки, не важно. Что у тебя в файле myclass.cpp? 
Код

MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}

остальное не важно.
Получается что компилятор компилирует два файла
myclass.cpp и myclassinst.cpp в обоих из них во время компиляции (поскольку include препроцессорная директива, она работает до компиляции) будет ДВА тела конструктора и деструктора. Для компилятора это не проблема, потому как он компилирует каждый cpp файл по отдельности и делает из них obj файлы. А потом наступает очередь линкера, он соединяет эти два obj файла и видет в обоих из них тело конструктора и деструктора того же класса. Потому и ошибка "already defined".
Это о причине возникновения ошибки. Теперь о решении
Если писать объявление в заголовочном файле а тело в cpp - это нормально, но в случае с шаблонным классом или функциями этого сделать не получиться (как я уже сказал, экспорт шаблонов). А делать include cpp файл неправильно. Если хочешь просто разделить их, сделай два .h файла.
myclass.h и myclass_impl.h и включай у себя в программе только myclass_impl.h (который в свою очередь включает myclass.h. Так ты просто разделишь их на два файла.
Вот так.

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 12:45
PM   Вверх
Леопольд
Дата 28.7.2009, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Brodyaga, вот небольшой пример.

Код

#include <iostream>

class Base{
    int data;
public:
    virtual void foo(int i = 0) = 0;
};

class Child: public Base{
public:
    virtual void foo(int i = 1){
        std::cout<<"Child::foo::i = "<<i<<std::endl;
    }
};



int main(int argc, char* argv[])
{
    Child obj;
    Base& ref = obj;

    ref.foo();
    obj.foo();
}


Вывод:
Код

Child::foo::i = 0
Child::foo::i = 1


Подсказка: функции линкуются динамически, аргумент по умолчанию статически.
Если подсказка не объясняет почему так происходит, значит надо уделить немного внимания линковке

Судя по Вашим топикам, Вы очевидно не знаете что такое ODR - One Definition Rule (Правило Одного Определения)


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 28.7.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Цитата

Если ты имеешь ввиду в файле myclassinst сменить инклуд myclass.cpp на myclass.h, то я говорю, что так работать не будет. Студия ругается на то что шаблон явно не инстанцирован.

Не совсем понял о чем речь.

ну если ты предлагаешь файл myclassinst.cpp сделать таким:
Код

#include "myclass.h"    //вместо myclass.cpp

#include "ClassA.h"
#include "ClassB.h"

template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);

то так работать не будет.

Цитата

Смотри.
Что делает include? ничего особенного, просто берет содержимое одного файла и копирует в другой (грубо говоря). Т.е. вместо
#include "myclass.cpp"
у тебя будет содержимое файла myclass.cpp и дальше какие-то строки, не важно. Что у тебя в файле myclass.cpp? 

Код

MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}



остальное не важно.
Получается что компилятор компилирует два файла
myclass.cpp и myclassinst.cpp в обоих из них во время компиляции (поскольку include препроцессорная директива, она работает до компиляции) будет ДВА тела конструктора и деструктора. Для компилятора это не проблема, потому как он компилирует каждый cpp файл по отдельности и делает из них obj файлы. А потом наступает очередь линкера, он соединяет эти два obj файла и видет в обоих из них тело конструктора и деструктора того же класса. Потому и ошибка "already defined".
Это о причине возникновения ошибки.

Это я уже понял после поста UnrealMan'а smile

Цитата

Если писать объявление в заголовочном файле а тело в cpp - это нормально, но в случае с шаблонным классом или функциями этого сделать не получиться (как я уже сказал, экспорт шаблонов)

в случае с шаблонным классом получается как раз таки через способ что я приводил в каком то из предыдущих постов.

Цитата

А делать include cpp файл неправильно

Вот гдето я видел что так делается, поэтому и так сделал у себя... К сожаление не смог сейчас найти где это видел.. так что соглашусь.

А как всё-таки вам способ с включением строк
Код

template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);


в файл myclass.cpp ?
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  14:15 Найти цитируемый пост)
ну если ты предлагаешь файл myclassinst.cpp сделать таким:

Я этого не предлагал.
Я только две вещи предложил, оба с этим не имеют ничего общего.

Цитата(azesmcar @  28.7.2009,  11:01 Найти цитируемый пост)
1. Я предлагаю писать шаблонные функции в заголовочном файле (это я рекомендую, это не криво. Так написан весь STL)
2. Если не хочешь - я предлагаю сменить расширение своего файла (myclass.cpp) на myclass.h например или убери его из проекта вообще, чтобы не компилировался. (правый клик мышки на файле в solution explorer, rename/delete). 


Цитата(Brodyaga @  28.7.2009,  14:15 Найти цитируемый пост)
в случае с шаблонным классом получается как раз таки через способ что я приводил в каком то из предыдущих постов.

нет, мы говорим о разных вещах. Почитай о translation юнитах.

Цитата(Brodyaga @  28.7.2009,  14:15 Найти цитируемый пост)
Вот гдето я видел что так делается, поэтому и так сделал у себя... К сожаление не смог сейчас найти где это видел.. так что соглашусь.

Ну мало ли кто как пишет. Всего повторять не надо, даже микрософтовские заголовки и функции зачастую не пример для подражания.
Хочешь пример качественного кода? Смотри boost smile 

Цитата(Brodyaga @  28.7.2009,  14:15 Найти цитируемый пост)
А как всё-таки вам способ с включением строк

Я только ЗА 1-ый вариант, включить все в заголовочный файл.
Ну или хотя бы вот этот
Цитата(azesmcar @  28.7.2009,  12:42 Найти цитируемый пост)
Если хочешь просто разделить их, сделай два .h файла.
myclass.h и myclass_impl.h и включай у себя в программе только myclass_impl.h (который в свою очередь включает myclass.h. Так ты просто разделишь их на два файла.


PM   Вверх
Brodyaga
Дата 28.7.2009, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

в случае с шаблонным классом получается как раз таки через способ что я приводил в каком то из предыдущих постов.


ну вот же я указывал...
myclass.h
Код

template<class T>
class MyClass
{
public:
   MyClass();
   ~MyClass();
   static T* MyFunc(T*);
};


myclass.cpp
Код

template <class T>
MyClass<T>::MyClass()
{
}
template <class T>
MyClass<T>::~MyClass()
{
}
template <class T>
T* MyClass<T>::MyFunc(T* object)
{
 return null;
}



myclassinst.cpp
Код

/*Файл реализующий "модель явного воплощения" для организации кода с шаблонами*/
#include "StdAfx.h"
#include "myclass.cpp"
#include "ClassA.h"
#include "ClassB.h"
//Набор директив явного воплощения
template MyClass<ClassA>;
template MyClass<ClassB>;


Шаблонный класс разнесён на определение и реализацию. и явное инстанцирование применяю и всё работает!

Зачем тогда вообще явное инстанцирование нужно, если вы говорите, что надо просто тупо помещать всё в h файл и всё ок без него работает!??!
PM MAIL   Вверх
azesmcar
Дата 28.7.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  28.7.2009,  14:59 Найти цитируемый пост)
Зачем тогда вообще явное инстанцирование нужно, если вы говорите, что надо просто тупо помещать всё в h файл и всё ок без него работает!??! 

В C++ есть много чего, что не используется на практике. Хотя бы потому, что надобности нет. Ну вот объясни мне, зачем в твоем случае это нужно? Что это тебе дает кроме проблем? (проблема в том, что вместо того чтобы дописать код, ты целый день это обсуждаешь..ну чем не проблема?). Тебе обязательно надо использовать все возможности, которые дает C++ в одной своей программе? Скажи мне о преимуществах твоего варианта по отношению к моему (как ты выразился: тупо поместить все в .h файле).

Это сообщение отредактировал(а) azesmcar - 28.7.2009, 15:12
PM   Вверх
Леопольд
Дата 28.7.2009, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Brodyaga @ 28.7.2009,  14:59)
#include "myclass.cpp"
...
Шаблонный класс разнесён на определение и реализацию. и явное инстанцирование применяю и всё работает!

Зачем тогда вообще явное инстанцирование нужно, если вы говорите, что надо просто тупо помещать всё в h файл и всё ок без него работает!??!

Это абсолютно тоже самое, что полностью перенести весь файл myclass.cpp в myclass.h и сделать #include "myclass.h"
Brodyaga, почитай про раздельную компиляцию, дело говорю.  smile 

Какая здесь связь, между явным инстанцированием и вынесением реализации шаблонов в отдельный модуль (которая почти ничем не поддерживается)??? Зачем вообще применять явное инстанцирование без насущной необходимости???

Это сообщение отредактировал(а) Леопольд - 28.7.2009, 17:55


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 28.7.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Brodyaga, сможешь объяснить почему foo<int>() выводит 0, а foo<char>() выводит 1?
first.h
Код

#ifndef FIRST_H
#define FIRST_H
#include <iostream>

static int i = 0;
void set_i(int);

template<typename T>
void foo(void){
    std::cout<<i<<std::endl;
}

#endif


main.cpp
Код

#include "first.h"

int main(void){
    set_i(1);
    foo<int>();
    foo<char>();
 }


first.cpp
Код

#include "first.h"

template void foo<char>(void);

void set_i(int i_){
    i = i_;
}


Это сообщение отредактировал(а) Леопольд - 28.7.2009, 18:11


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 29.7.2009, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

(проблема в том, что вместо того чтобы дописать код, ты целый день это обсуждаешь..ну чем не проблема?)

Этот код я всеровно сейчас не пишу, другим пока занимаюсь. Поэтому можно и пообсуждать smile

Цитата

Скажи мне о преимуществах твоего варианта по отношению к моему (как ты выразился: тупо поместить все в .h файле).

Ну положено же разносить определение и реализацию в разные файлы. В моём случае так и получается. А то както некрасивше, когда некоторые классы разнесены, а не которые нет...

Цитата

Какая здесь связь, между явным инстанцированием и вынесением реализации шаблонов в отдельный модуль (которая почти ничем не поддерживается)???

Конкретно между ними - никакой. Просто я хочу и то и то сделать. Я не говорю что явное инстанцирование это обязательно разнесение! Я говорю что с помощью него можно сказать компилятору какое воплощение будет у шаблона, если шаблон разнесён по файлам, так как если шаблон в одном файле, то не надо говорить компилятору какое воплощение будет.
PM MAIL   Вверх
azesmcar
Дата 29.7.2009, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  29.7.2009,  07:29 Найти цитируемый пост)
Ну положено же разносить определение и реализацию в разные файлы. 

Кто это так положил? Для шаблонных функций и классов так не положено, я об этом твержу 2 страницы. Посмотри как сделан boost, STL. Не положено так. Но раз тебя это так заботит, скажи мне зачем так положено?
Почему лучше разносить определение и реализацию в разные файлы? Что это дает и почему так рекомендуется?

Цитата(Brodyaga @  29.7.2009,  07:29 Найти цитируемый пост)
А то както некрасивше, когда некоторые классы разнесены, а не которые нет...

Не вижу ничего некрасивого.
PM   Вверх
Леопольд
Дата 29.7.2009, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Brodyaga @ 29.7.2009,  07:29)
Ну положено же разносить определение и реализацию в разные файлы. В моём случае так и получается. А то както некрасивше, когда некоторые классы разнесены, а не которые нет...

Brodyaga, это не так. Дело не в том что положено, а в том как тебе нужно.

Следующий пример содержит ошибки, потому-что static функции линкуются статически - на этапе компиляции (однако, это не относится к static методам (функциям) класса). Функции с квалификатором inline - вообще отдельная тема. Если же убрать вызовы foo1 и foo2 из main, то всё будет работать. Что бы узнать почему так, читай про раздельную компиляцию.

header.h
Код

static void foo1(int&);
inline void foo2(int&);
void foo3(int&);

second.cpp
Код

#include "header.h"
static void foo1(int& i){
    ++i;
}

inline void foo2(int& i){
    ++i;
}

void foo3(int& i){
    foo1(i);
    foo2(i);
}


first.cpp
Код

#include "header.h"

int main(int argc, char* argv[])
{
    int i = 0;
    foo1(i); //error
    foo2(i); //error
    foo3(i); //OK
}


Заметил, что ты всё же мельком просматриваешь мои посты. Рекомендую уделить им чуть больше внимания.

Добавлено через 13 минут и 50 секунд
Цитата(Brodyaga @ 29.7.2009,  07:29)
Конкретно между ними - никакой. Просто я хочу и то и то сделать. Я не говорю что явное инстанцирование это обязательно разнесение! Я говорю что с помощью него можно сказать компилятору какое воплощение будет у шаблона, если шаблон разнесён по файлам, так как если шаблон в одном файле, то не надо говорить компилятору какое воплощение будет.

 smile Ничего не понятно...
Может всё же сначала ознакомишься с вопросом, прежде чем пытаться что-то делать? Это будет гораздо быстрее, чем "медотом тыка".

Реализацию функций выносят в отдельный cpp файл отнюдь не ради красоты, а для РАЗДЕЛЬНОЙ КОМПИЛЯЦИИ. Насколько мне известно, к шаблонам это относиться в той же степени.

Это сообщение отредактировал(а) Леопольд - 29.7.2009, 10:16


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 29.7.2009, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Может всё же сначала ознакомишься с вопросом, прежде чем пытаться что-то делать? Это будет гораздо быстрее, чем "медотом тыка".

Реализацию функций выносят в отдельный cpp файл отнюдь не ради красоты, а для РАЗДЕЛЬНОЙ КОМПИЛЯЦИИ. Насколько мне известно, к шаблонам это относиться в той же степени.

РАЗДЕЛЬНАЯ КОМПИЛЯЦИЯ ФОРЕВЕР! Все дружно начинаем молиться на неё!!!  smile 

Цитата

smile Ничего не понятно...

а я не понимаю к чему столько флуда про раздельную компиляцию и какие то непонятные вопросы мне о ней. Если чтото конкретно хочешь по моему примеру сказать, то скажи.

Цитата

Почему лучше разносить определение и реализацию в разные файлы? Что это дает и почему так рекомендуется?

Чтобы подключать определения определённых классов в местах где они нужны и чтобы вместе с ними не подключалась каждый раз вся реализация.
Или если изменится чтото только в реализации, то придётся перекомпилировать и слинковать только её. Ну вообщем.. раздельная компиляция (Леопольд! ВНИМАНИЕ! smile)))))))

Цитата

Не вижу ничего некрасивого.

Ну хорошо... а чем не нравится метод включения строк 
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);

в файл myclass.cpp ?

Это сообщение отредактировал(а) Brodyaga - 29.7.2009, 14:56
PM MAIL   Вверх
azesmcar
Дата 29.7.2009, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  29.7.2009,  14:55 Найти цитируемый пост)
Чтобы подключать определения определённых классов в местах где они нужны и чтобы вместе с ними не подключалась каждый раз вся реализация.
Или если изменится чтото только в реализации, то придётся перекомпилировать и слинковать только её. 

Да (можно еще найти причины, но этой достаточно), а теперь смотри, добиться того, что ты описал в случае с шаблонами можно ТОЛЬКО ИСПОЛЬЗОВАВ ЭКСПОРТ ШАБЛОНОВ. Так зачем мучиться если все равно цель недостижима? Включив CPP файл инклудом ты желаемого не получишь все равно. Потому я и говорю, пиши в заголовочном файле.

Цитата(Brodyaga @  29.7.2009,  14:55 Найти цитируемый пост)
template ClassA* MyClass::MyFunc<ClassA>(ClassA* object);
template ClassB* MyClass::MyFunc<ClassB>(ClassB* object);

в файл myclass.cpp ?

Понимаешь, не нужна причина чтобы чего-то не делать, нужна причина чтобы делать. Назови мне причину, ты выполняешь определенные действия, для чего? что ты получаешь от этого? Затрудняешь чтение и сопровождение своей программы. Что ты получаешь взамен? Если назовешь себе хоть одну весомую причину - делай так.  smile 

Это сообщение отредактировал(а) azesmcar - 29.7.2009, 15:39
PM   Вверх
andrew_121
Дата 29.7.2009, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

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



Brodyaga, Если кого-то цитируете, выделяйте текст, и нажимайте кнопочку "Быстрая цитата". Так как не понятно кого вы цитируете.


п.с.
Ощущение, что Brodyaga не способ решения ищет, а способ все усложнить.



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Brodyaga
Дата 29.7.2009, 18:01 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Назови мне причину, ты выполняешь определенные действия, для чего? что ты получаешь от этого? Затрудняешь чтение и сопровождение своей программы. Что ты получаешь взамен?

Ну как же... Шаблон будет разделён на два файла h и cpp. где надо там я буду подкючать h файл. И не будет никакого инклуда cpp файла.
Тоесть всё как я и хотел но без файла myclassinst.cpp

Цитата

п.с.
Ощущение, что Brodyaga не способ решения ищет, а способ все усложнить.

smile)))))) Нет. Просто хочу понять почему другие варианты плохи.

Это сообщение отредактировал(а) Brodyaga - 29.7.2009, 18:24
PM MAIL   Вверх
azesmcar
Дата 29.7.2009, 19:56 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  29.7.2009,  18:01 Найти цитируемый пост)
Ну как же... Шаблон будет разделён на два файла h и cpp. где надо там я буду подкючать h файл. И не будет никакого инклуда cpp файла.
Тоесть всё как я и хотел но без файла myclassinst.cpp

Да, это вариант..и ты даже получишь желаемое, но за счет чего? Теперь каждый раз когда тебе нужно использовать шаблон для нового типа, придется лезть в файл и добавлять строку, а если ты хочешь использовать свой шаблон для типа, который не известен твоему cpp файлу? Дополнительно делать в него include. Так твой cpp файл скоро разрастется, а что если завтра ты решишь что твой шаблонный класс это шедевр созданный твоими собственными руками и ты решишь увековечить его в виде lib-ы. Как потом пользователи твоей библитеки будут использовать твой шаблонный класс со своими типами? Тут теряется мощь шаблонов в некотором смысле. Если это устраивает - пиши.
PM   Вверх
Леопольд
Дата 29.7.2009, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Brodyaga @ 29.7.2009,  14:55)
Цитата

Почему лучше разносить определение и реализацию в разные файлы? Что это дает и почему так рекомендуется?

Чтобы подключать определения определённых классов в местах где они нужны и чтобы вместе с ними не подключалась каждый раз вся реализация.
Или если изменится чтото только в реализации, то придётся перекомпилировать и слинковать только её. Ну вообщем.. раздельная компиляция (Леопольд! ВНИМАНИЕ! smile)))))))

Судя по всему, этим твои знания о раздельной компиляции и ограничиваются . Это тоже самое, что сказать - "С++ это язык программирования, и он нужен для того чтобы писать на нём программы". Но если это всё что человек знает про С++, то программистом его назвать нельзя, не так ли? Мои вопросы тебе непонятны именно потому что ты не знаешь как именно работает раздельная компиляция, в том числе и с шаблонами. Я советую тебе, изучить этот вопрос, потому что если бы ты знал его, то не начал бы этот топик вообще smile

Вот ещё один "непонятный" примерчик того что ты не знаешь как работает линковка. Я предполагаю что ты не знаешь этого потому что ты ни на один "непонятный" вопрос до сих пор не ответил ничего вразумительного:

Почему не компилируется вот это?
header.h
Код

class Example{
public:
    void Foo();
};

void Example::Foo(){
}

first.cpp
Код

#include "first.h"

int main(void){
    Example obj;
    obj.Foo();
    return 0;
}

second.cpp
Код

#include "first.h"
// только #include, больше ничего нет


А вот это, почти тоже самое, компилируется без проблем.
header.h
Код

class Example{
public:
    inline void Foo();
};

void Example::Foo(){
}

first.cpp
Код

#include "first.h"

int main(void){
    Example obj;
    obj.Foo();
    return 0;
}

second.cpp
Код

#include "first.h"
// только #include, больше ничего нет


А вот это, тоже не компилируется
header.h
Код

class Example{
public:
    inline void Foo();
};

first.cpp
Код

#include "first.h"

int main(void){
    Example obj;
    obj.Foo();
    return 0;
 }

second.cpp
Код

#include "first.h"

void Example::Foo(){
}


Добавлено @ 21:12
Цитата(Brodyaga @ 29.7.2009,  18:01)
И не будет никакого инклуда cpp файла.

Этого вообще никогда не должно быть. Для этого есть *.h или, частенько, в случае с шаблонами, *.hpp

Это сообщение отредактировал(а) Леопольд - 29.7.2009, 21:16


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 29.7.2009, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(Леопольд @  29.7.2009,  20:05 Найти цитируемый пост)
или, частенько, в случае с шаблонами, *.hpp

шаблоны тут не при чем smile 
си - *.c и *.h
cpp - *.cpp *.hpp (ну а *.h им достались по наследству smile ) 



--------------------
PM MAIL WWW   Вверх
Brodyaga
Дата 30.7.2009, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Судя по всему, этим твои знания о раздельной компиляции и ограничиваются .

Это что экзамен чтоли? я тебе должен сейчас всё рассказать, что знаю про раздельную компиляцию?

Цитата

Вот ещё один "непонятный" примерчик того что ты не знаешь как работает линковка. Я предполагаю что ты не знаешь этого потому что ты ни на один "непонятный" вопрос до сих пор не ответил ничего вразумительного

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

Цитата

Да, это вариант..и ты даже получишь желаемое, но за счет чего? Теперь каждый раз когда тебе нужно использовать шаблон для нового типа, придется лезть в файл и добавлять строку, а если ты хочешь использовать свой шаблон для типа, который не известен твоему cpp файлу? Дополнительно делать в него include. Так твой cpp файл скоро разрастется, а что если завтра ты решишь что твой шаблонный класс это шедевр созданный твоими собственными руками и ты решишь увековечить его в виде lib-ы. Как потом пользователи твоей библитеки будут использовать твой шаблонный класс со своими типами? Тут теряется мощь шаблонов в некотором смысле. Если это устраивает - пиши.

Можно эти строки вынести в отдельный h. Ну вообщем-то я тебя понял, спасибо! Буду выбирать, что для меня лучше. +1! ;)
PM MAIL   Вверх
azesmcar
Дата 30.7.2009, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Brodyaga @  30.7.2009,  06:57 Найти цитируемый пост)
Можно эти строки вынести в отдельный h. 

Можно, но это ничего не даст...нет, тоесть даст, просто сгруппирует все это безобразие в одном файле, но проблем это не отменит.
PM   Вверх
Леопольд
Дата 30.7.2009, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Brodyaga @ 30.7.2009,  06:57)
И не собираюсь отвечать. Даже читать твои этажи кода не хочу. Я тебе не собираюсь ничего доказывать о своих знаниях. Если хочешь обсудить раздельную компиляцию, создай отдельную тему.

Эти "этажи" настолько элементарны, что не заслужили такого названия smile Мне никаких доказательств не надо, я знаю достаточно о линковке, что-бы использовать её себе во благо, и у меня не возникает вопросов, почему же проект, из 30 файлов не компилируется. А вот у тебя они возникают. Это не мне, а тебе надо понять, что для тебя остались тёмные уголки... Это единственная цель, которую я преследовал.

Это сообщение отредактировал(а) Леопольд - 30.7.2009, 09:49


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Brodyaga
Дата 30.7.2009, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

А вот у тебя они возникают.

И у меня не возникают. Всё прекрасно компилируется. Просто возник небольшой казус с шаблонами, так как определялись повторно конструктор и деструктор. А так всё норм, выслушал плюсы и минусы явного инстанцирования и полного включения. Далее обсуждать чтото в этой теме не намерен. 

Цитата

я знаю достаточно о линковке, что-бы использовать её себе во благо

Если тебе хочется показать всем насколько ты круто знаешь линковку, то для этого не нужно флудить о ней в этой теме и задавать мне вопросы. Просто напиши статейку и выложи её здесь. Думаю это на самом деле будет полезно, без шуток.
PM MAIL   Вверх
Леопольд
Дата 30.7.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(Brodyaga @  30.7.2009,  09:52 Найти цитируемый пост)

Цитата(Леопольд @  30.7.2009,  08:59 Найти цитируемый пост)
А вот у тебя они возникают.

И у меня не возникают. Всё прекрасно компилируется.

Мне так показалось из твоих постов, но я не уверен в этом. Возможно, ты просто очень сильно не любишь отвечать на вопросы.

Цитата(Brodyaga @  30.7.2009,  09:52 Найти цитируемый пост)
Если тебе хочется показать всем насколько ты круто знаешь 

Я не бахвалился...  smile   Психологический трюк  smile  Однако, очевидно, что ты враждебно настроен. Воспринимаешь искажённо.

Добавлено через 7 минут и 6 секунд
Цитата(Brodyaga @  30.7.2009,  09:52 Найти цитируемый пост)
Просто возник небольшой казус с шаблонами ... то для этого не нужно флудить о ней в этой теме и задавать мне вопросы.

Дело в том, что я вижу непосредвенную связь между, линковкой и инстанцирванием шаблонов. Я задавал наводящие вопросы, но увы, всё зря...

Добавлено через 10 минут и 9 секунд
По шаблонам есть неплохая книга - "Шаблоны С++. Справочник разработчика". Местами тяжеловато написанно, но там раскрыто много вопросов.

Это сообщение отредактировал(а) Леопольд - 30.7.2009, 12:18


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 30.7.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(mes @ 29.7.2009,  23:54)
си - *.c и *.h
cpp - *.cpp *.hpp (ну а *.h им достались по наследству smile )

Я заметил, случайно (если мне вообще не показалось) что кое-кто в *.h держит всякие разные объявления + реализации inline функций (глобальные переменные не рассматриваю), соответственно в *.сpp определения не inline фукнций. 
static функции могут быть определенны в хидере только если это не члены класса (inline static тоже можно определить в хидере, в том числе, если функция - член класса)

В *.hpp шаблоны - реализация которых, как правило, находится там же, независимо от линковки. Мне это показалось удобным, и я делаю именно так smile

Это сообщение отредактировал(а) Леопольд - 30.7.2009, 15:48


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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