Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 38 из 87<  1 ... 35  36  37  38  39  40  41 ... 87  >
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Добрый день!!!
Я решил изучить чистый C, но возникла вечная проблема выбора компилятора. Что посоветуете?



Партнер
 

Member
Статус: Не в сети
Регистрация: 18.11.2002
Откуда: не вернуться
Под Win мне нравится Dev-C++ маленький и удобный, сам он по себе IDE с компилятором MinGW

_________________
Летели гуси-лебеди, а им навстречу - воробьи-пингвины и соловьи-страусы...


 

Member
Статус: Не в сети
Регистрация: 11.04.2004
Откуда: СПБ
MinGW + gcc


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Как вообще нужно шаблоны программировать - с включением или разделением? Решил делать с разделением:
Код:
export template<class T>
class GraphicsModelItem : public MObject, public T
{
.....
}

Выдает ошибки
error C2143: syntax error : missing ';' before ''template<''
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Catar писал(а):
MinGW + gcc
Какое масло использовать? Сливочное + подсолнечное :-D

kexman писал(а):
Как вообще нужно шаблоны программировать - с включением или разделением? Решил делать с разделением:
Э нее, не трогай ты этот export, он нормально еще нигде не работает, точно также как и шаблонные виртуальные ф-ции.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
мне нужно в общем вынести функцию из определения шаблона:
Код:
template<class T>
class GraphicsModelItem : public MObject, public T
{
...
private:
   int detectPosition(QPointF pos);
...
}

cpp файл
#include "graphicsmodelitem.h"

template<class T>
int GraphicsModelItem<T>::detectPosition(QPointF pos)
   {
              ....
   }

Линковщик выдает ошибку


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman по объективным причинам, ты не можешь вынести определение из h файла.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon
Привет! В чем прикол месяц назад у меня это как-то работало, выносил я в cpp файл функции члены, причем без export, но в упор не помню как :(. Тогда же заметил странную особенность - обычные функции выносились, а виртуальные - никак. А внутри определения класса виртуальные функции нормально работают вроде.
Добавлено спустя 25 минут, 15 секунд
повозился еще с этим делом, короче если просто вынести функцию, даже без export, компилируется нормально, если же она где-то используется, то вылазит ошибка линковщика.


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
kexman писал(а):
повозился еще с этим делом, короче если просто вынести функцию, даже без export, компилируется нормально, если же она где-то используется, то вылазит ошибка линковщика.
В C++ используется модель раздельной компиляции. Единица трансляции - один cpp-файл, каждый из них компилируется абсолютно независимо от других. Т.е. компилятор, обрабатывая твой файл, в который ты вынес определения шаблонных методов, ничего не знает об использовании этих методов в других файлах. В результате скомпилируются, только те (блин, слово забыл :)) методы, которые ты инстанцируешь в этом файле. Соответственно, если там ничего кроме шаблонов нет, то ничего и не скомпилируется. Так что размещай шаблоны целиком в подключаемом файле.


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Но ведь в стандарт предусматривает раздельную компиляцию, я так понимаю. Даже в книжках 4х-летней давности это описано.
Добавлено спустя 13 минут
Еще вопросик появился - есть класс, унаследованный от двух базовых. Есть функция, принимающая указатель на первый базовый класс. Есть объект производного класса. Можно ли этой функции подсунуть указатель на этот объект, типа первого класса:
Код:
class Derived : public Base1, public Base2
{
...
};

void foo(Base1 *ptr)
{
...
}
...
Base2 *ptr = new Derived(...);
foo(reinterpret_cast<Base1>(ptr));

У меня почему-то вылетает с ошибкой.
Добавлено спустя 7 минут, 21 секунду
Причем и такой вариант также вызывает ошибку:
Код:
Derived *ptr = new Derived(...);
foo(reinterpret_cast<Base1>(ptr));

Что такого делает reinterpret_cast с указателем?


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
reinterpret_cast ничего не делает с указателем, и в этом ошибка и заключается. Ведь объект состоит из нескольких частей: унаследованной от Base1, унаследованной от Base2 и своей собственной. Указатель на Derived указывает, естественно, на начало объекта, и довольно часто там располагается часть Base1, но это ни кем не гарантировано. Приведение указателя на Derived к базовому типу, вообще говоря, осуществляет смещение этого указателя к началу требуемой части объекта, поэтому здесь нужен static_cast, который это и делает. А вообще указатель приводится к базовому типу автоматически, и явного приведения здесь не требуется.
Добавлено спустя 1 минуту, 41 секунду
З.Ы. А приводить указатель на Base2 к указателю на Base1 неправильно. Где-то у тебя ошибка в проектировании.
Добавлено спустя 2 минуты, 3 секунды
З.З.Ы. На раздельную компиляцию шаблонов просто забей, я ещё не видел, чтобы она где-то работала и её кто-то использовал, кроме авторов книжек.


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Билли Бонс
Да, вот я и думал насчет того, что фактически объект в памяти состояит из нескольких частей, и указатели как-то должны сдвигаться.
Насчет ошибки в проектировании - дело в том, что я пытаюсь прикрутить существующую библиотечную иерархию классов к своей иерархии в программе. Поэтому пришлось воспользоваться единственным возможным решением(спасибо Daemon'у за подсказку). Но это решение с точки зрения структуры программы не совсем хорошее. Если же проектировать правильно, то придется переписывать часть библиотечного кода, что тоже не есть гуд.


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Билли Бонс писал(а):
Приведение указателя на Derived к базовому типу, вообще говоря, осуществляет смещение этого указателя к началу требуемой части объекта, поэтому здесь нужен static_cast, который это и делает.
static_cast обязателен к использованию, если объекты используют виртуальные функции, потому как именно из-за указателя на таблицу виртуальных функций происходит смещение адреса наследуемого объекта.

kexman писал(а):
Если же проектировать правильно, то придется переписывать часть библиотечного кода, что тоже не есть гуд.
Гы, это не есть правильное проектирование, если его применение приводит к подобным вещам.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon
Может помнишь, ты мне уже помогал в этом вопросе. В библиотеке есть иерархия классов(порожденных от общего базового), и мне надо заиметь такую же у себя в программе, причем с добавлением своих свойств и методов в каждый класс. Ты посоветовал использовать шаблон вида
Код:
template<class T>
class GraphicsModelItem : public TObject, public T
{
...
}

Это наверное единственное решение в данном случае. Единственное что мне в нем не нравится - это то, что в разных функциях (в других частях программы), которые используют эти объекты, приходится в качестве параметров писать GraphicsModelItem<QGraphicsItem> (QGraphicsItem - базовый библиотечный класс иерархии объектов). А это - каждый раз инстанцирование шаблонов, что мне не очень нравится. Попытался заменить в параметрах функций GraphicsModelItem<QGraphicsItem> на TObject, и приводить потом где надо к QGraphicsItem - не получилось.
Добавлено спустя 5 минут, 23 секунды
кстати такой вопрос - при компиляции при инстанцировании шаблонов, появляется в окне output (MSVC) сооттветствующая надпись, что-то типа [T = Класс_который_подставляется]. Почему-то этого не происходит, когда использую библиотечные шаблоны. И еще. Когда я в программе 10 раз использую vector<int> - у меня 10 экзэмпляров класса vector<int> ?


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman писал(а):
приходится в качестве параметров писать GraphicsModelItem<QGraphicsItem> (QGraphicsItem - базовый библиотечный класс иерархии объектов)
Подожди, во-первых это в компаил тайме все происходит, а во-вторых для каждого нового типа, при инстанциировании шаблона, код генерируется один раз! Не понимаю, почему тебя это заботит.
Добавлено спустя 1 минуту, 41 секунду
kexman писал(а):
Когда я в программе 10 раз использую vector<int> - у меня 10 экзэмпляров класса vector<int> ?
Ыыыыы, экзепляров-то десять, но код сгенерировался один раз, иначе бы получил кучу редифинишинов.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon писал(а):
но код сгенерировался один раз, иначе бы получил кучу редифинишинов.

Это я и спрашивал. Понимаю. Блин с++ настолько сложный язык, куча разных мелких ньюансов, но зато жуть как интересно.

Недавно встретился со старым знакомым. Между делом у него промелькнуло в разговоре, что он "программит на сях". Ну я начал так для интереса спрашивать как он это делает. Боже мой! Вначале он сказал, что изучить язык ему помог его друг, а книжку Страуструпа он просмотрел только на предмет синтаксиса. Он говорит, что пользуется своими библиотеками, написанными им давно, в частности для работы с комплексными числами. На мои скромные попытки объяснить, что это все уже есть и написано лучшими программерами мира, он ответил, что зато сам это написал. Далее, спрашиваю - пользуешься контейнерами из стандартной библиотеки, он отвечает, что не пользуется, внимание!!, у него есть кусок кода с выделением памяти под объекты, который он каждый раз вставляет в код!! Я уже в шоке стою, говорю ему почитай книжки признанных гуру, там написано как надо программировать, он говорит - я так пишу, потому что я должен быть уверен в каждой, написанной мной строчке кода, поэтому он все пишет сам. Ну и в довесок что меня убило, говорит - "это все на вкус и цвет на самом деле, разницы нету, у каждого свой стиль, вот допустим есть две формы для выделения памяти - malloc и new. Я пользуюсь malloc, мне так больше нравится". Говорит, что пишет программы вместе с другом, у них есть какое-то внутреннее соглашение, как надо писать, они его придерживаются :) Еще у него промелькнуло, что думает еще на счет дальнейшего трудоустройства (он также как и я на 4м курсе, но специальность не связанная с информационными технологиями) - говорит, может программером устроится :) Я чуть не расплакался ). Собственно программы он пишет для расчетов, связанных с его специальностью.
Короче бывают и такие :)


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman писал(а):
Это я и спрашивал. Понимаю. Блин с++ настолько сложный язык, куча разных мелких ньюансов, но зато жуть как интересно
Везде есть свои ньюансы.

kexman писал(а):
"это все на вкус и цвет на самом деле, разницы нету, у каждого свой стиль, вот допустим есть две формы для выделения памяти - malloc и new

Да, это конечно он мастер :-D

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 24.12.2005
Daemon писал(а):
static_cast обязателен к использованию, если объекты используют виртуальные функции, потому как именно из-за указателя на таблицу виртуальных функций происходит смещение адреса наследуемого объекта.
Разве? По-моему всегда проходит неявное преобразование. Я, собственно, писал о том, что это неявное преобразование делает static_cast, а не reinterpret_cast. Может, просто выразился туманно.
kexman писал(а):
Единственное что мне в нем не нравится - это то, что в разных функциях (в других частях программы), которые используют эти объекты, приходится в качестве параметров писать GraphicsModelItem<QGraphicsItem> (QGraphicsItem - базовый библиотечный класс иерархии объектов). А это - каждый раз инстанцирование шаблонов, что мне не очень нравится. Попытался заменить в параметрах функций GraphicsModelItem<QGraphicsItem> на TObject, и приводить потом где надо к QGraphicsItem - не получилось.
Хм, а typedef не судьба сделать? :)
Добавлено спустя 3 минуты, 42 секунды
kexman К сожалению, такими программистами написано процентов, наверное, 90 от всего когда-либо созданного кода... Так что твой товарищ не одинок. :)


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Билли Бонс
Нет ну блин, я скорее всего не буду программистом по профессии, потому что реально оцениваю свои силы :) Но все равно, хоть это и хобби, стараюсь делать все не абы как. Неужели сложно читать книжки и советоваться с людьми??


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
Билли Бонс писал(а):
Я, собственно, писал о том, что это неявное преобразование делает static_cast, а не reinterpret_cast. Может, просто выразился туманно.
Да, тут прав, не понял изначально.
Добавлено спустя 2 минуты, 29 секунд
kexman писал(а):
я скорее всего не буду программистом по профессии, потому что реально оцениваю свои силы
Ты лучше смотри, по какой специальности больше платят, туда и иди :-D
Добавлено спустя 7 минут, 45 секунд
Кстати, насчет static_cast, кто скажет, какие в этом коде недостатки:
Код:
class clA
{

};
class cbB : public clA
{

};

.
.
.

clB b;
clA &a = static_cast<clA>(b);

_________________
Ку ку


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 38 из 87<  1 ... 35  36  37  38  39  40  41 ... 87  >
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan