forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Undefined reference to... (http://forum.boolean.name/showthread.php?t=13896)

Mr_F_ 17.12.2010 18:14

Ответ: Undefined reference to...
 
короче попробуй вместо =0 сделать
virtual void Update()
{
}
virtual Animal* Create()
{
}

wolfhound512 17.12.2010 18:22

Ответ: Undefined reference to...
 
Я к "элите" С++ не отношусь, поэтому попробую помочь.

В 2008-й студии этот код компилируется нормально, и даже работает. Думаю что для твоего компилятора просто стоит указать квалификатор "virtual"
Код:

class Animal1 : public Animal
{
      public:
            virtual void Update();
            virtual Animal* Create();
      protected:
};

Кроме того не ясно зачем тебе виртуальная функция Create. Если я правильно понял ее назначение, то тебе следует сделать ее статической (static)

UPD: Нет, virtual указывать не обязательно, ошибка наверное действительно "где-то в коде, который нам не был продемонстрирован"

.Squid 17.12.2010 18:38

Ответ: Undefined reference to...
 
Цитата:

Сообщение от Mr_F_ (Сообщение 172206)
короче попробуй вместо =0 сделать
virtual void Update()
{
}
virtual Animal* Create()
{
}

Я это и имел в виду. Только вот Create() возвращать еще че-то должен.

wolfhound512 17.12.2010 18:45

Ответ: Undefined reference to...
 
Цитата:

Сообщение от .Squid (Сообщение 172212)
Я это и имел в виду. Только вот Create() возвращать еще че-то должен.

А если ему нужен именно абстрактный класс?

.Squid 17.12.2010 18:50

Ответ: Undefined reference to...
 
Цитата:

Сообщение от wolfhound512 (Сообщение 172214)
А если ему нужен именно абстрактный класс?

Ну, я предполагаю, что ошибка где-то в коде, который нам не был продемонстрирован.

Reizel 17.12.2010 23:58

Ответ: Undefined reference to...
 
Блин, я забыл, что функция Create() статичной должна быть, переписал - все заработало...

...и даже правильно заработало! :-D

UPD Dev C++ странная IDE какая-то: при первой попытке скомпилить код - выдает кучу варнингов, даже если нет ошибок, а работает только после повторного нажатия f9

Цитата:

Сообщение от Knightmare (Сообщение 172190)
Если начинающий - идиот, то зафига тут изображать из себя кэпа объясняя ему очевидные вещи?

Я этот код написал через 10 минут прочтения книги по С++, и у некоторых он даже работал. А раз ты такой "умный", хуле ж сразу не объяснил чо к чему?? Че то от тебя еще не замечено было нормальных постов, а?

Samodelkin 18.12.2010 04:21

Ответ: Undefined reference to...
 
Можно сделать вот так:
class.hpp
Код:

#ifndef __CLASS_H__
#define __CLASS_H__

#include <stdio.h>
#include <iostream>

// Абстрактный базовый класс животного
class Animal {
protected:
        short maxHealth; // Максимальное количество HP
       
public:
        Animal(short h); // Конструктор класса в который можно передавать количество HP
        virtual Animal* Create() = 0; // Интерфейс для доступа к виртуальным методам суперклассов
       
        // Статическая функция с шаблоном вида животного.
        // Статическая для того чтобы ее можно было вызывать даже когда нету ни одного объекта и чтобы соблюдать правила инкапсуляции
        // Статические методы могут работать только со статическими данными класса.
        template<typename T> static Animal* CreateAnimal(short h) {
                std::cout << "Animal::Create" << std::endl;
                population++; // Увеличиваем популяцию на один
                return new T(h);
        }

        static int population; // Статическая переменная - сущетсвует вне объектов, фиксирует общее количество животных
};


// Класс животного КАБАН
class WildBoar : public Animal {
public:
        WildBoar(short h);
        virtual Animal* Create(); // Может производить сородичей
};


// Клас животного ВОЛК
class Wolf : public Animal {
public:
        Wolf(short h);
        virtual Animal* Create(); // Также может производить сородичей
};

#endif

class.cpp
Код:


#include "class.h"

// Конструктор класса Animal вызывается в конструкторах других реальных классов
Animal::Animal(short h) :
maxHealth(h)
{ };

WildBoar::WildBoar(short h) :
Animal(h) // Вот тут вызываем конструктор базового класса
{ }

Animal* WildBoar::Create() {
        std::cout << "WildBoar::Create" << std::endl;
        CreateAnimal<WildBoar>(100); // Передаем тип вместе с количеством HP
}

Wolf::Wolf(short h) :
Animal(h)
{ }

Animal* Wolf::Create() {
        std::cout << "Wolf::Create" << std::endl;
        CreateAnimal<Wolf>(50);
}

main.cpp
Код:

#include "class.h"

// population статическая переменная а значит она уже создана.
// Нужно указать компилятору что она в другой единице трансляции чтобы ее использовать тут.
extern int Animal::population;

int main() {

        // Инициализируем
        Animal::population = 0;
       
        // Тут еще 0
        std::cout << Animal::population << std::endl;
       
        // Можно создать указатели на любого животного и создать их через статическую функцию
        Animal* wb = Animal::CreateAnimal<WildBoar>(100);
        Animal* wf    = Animal::CreateAnimal<Wolf>(50);
       
        // Теперь их двое
        std::cout << Animal::population << std::endl;
       
        // Животные могут сами себя производить - каждый свой тип (если не указано иное в методах Create)
        wb->Create();
        wf->Create();
       
        // Теперь их четверо
        std::cout << Animal::population << std::endl;
       
        return 0;
}

Насчет ошибки из первого поста вероятней всего компоновщику не указан объектный файл с методами класса.

jimon 18.12.2010 13:15

Ответ: Undefined reference to...
 
не забываем о виртуальном деструкторе в class Animal, а то потом кучу геморроя заимеем

ps. для скорости я убираю virtual в методах которые мне явно не понадобится переопределять, а virtual ... = 0 находится только в декларациях методов интерфейса
те так :
Код:

class WildBoar : public Animal {
public:
        WildBoar(short h);
        Animal* Create(); // Может производить сородичей
};

теперь если мы вызываем вот это :
Код:

Animal * foo = new WildBoar;
...
foo->Create();

то во второй строчке произойдет обращение к виртуальной таблице методов, и вызов метода по смещению от туда

но если написать так :
Код:

Animal * foo = new WildBoar;
...
WildBoar * bar = static_cast<WildBoar*>(foo); // мы уверенны на все 100% что это WildBoar
bar->Create();

то вызов bar->Create(); выполнится напрямую, смещение метода посчитается во время компиляции и не будет никаких тормозов

хочу заметить что в данном случае нет никакого RTTI, и его использовать тоже не стоит (так же как и try...catch), в геймдеве рискуют статическим методом предоставления безопасности кода, а пользуются здравым смыслом :)

falcon 18.12.2010 15:50

Ответ: Undefined reference to...
 
Цитата:

Эх, что-то последнее время наша "элита" С++ программистов любит только издеваться над начинающими. Практически не помню нормальных ответов... к сожалению.
У вас, уважаемый, паранойя уже.
Элита стебётся? Так и надо т.к. C++ не терпит идиотов.
На подобные вопросы ответы лежат в литературе, которую должно быть не лень читать. Если человек через 10 минут после прочтения книги не может написать примитивный код, то ему либо надо перечитать всё заново и повнимательнее, либо он идиот, и лучше пускай забудет об этом языке.

Такое ощущение будто фразы типа "жаль что перестали помогать", "булкостайл" и т.п. - просто какая-то новая фишка. Фразы на все времена.
Очнитесь блин. Элите НЕ ИНТЕРЕСНО отвечать на тупые вопросы. Это пустая трата времени. Вменяемый новичок должен сам учиться искать ответы на тривиальные вопросы. И это НОРМАЛЬНО. Вменяемых новичков это стимулирует учиться искать ответы самим, а невменяемых отсеивает от сферы деятельности. Так и должно быть.
http://segfault.kiev.ua/smart-questions-ru.html

Nuprahtor 18.12.2010 16:13

Ответ: Undefined reference to...
 
Человек, не знающий C++ - идиот

IGR 18.12.2010 18:46

Ответ: Undefined reference to...
 
Идиот, ты тупой, какое отношение имеешь ты к с++ ??
Зы: Достоевский Ф. М. - "Идиот" !!

pax 18.12.2010 19:03

Ответ: Undefined reference to...
 
Цитата:

Сообщение от falcon (Сообщение 172314)
Элите НЕ ИНТЕРЕСНО отвечать на тупые вопросы.

Элите интересно стебаться над всеми начинающими. Да, я это уже понял. Спасибо, что напомнил.

PS: Возможно я не точно воспроизведу сказанную нашим админом когда-то фразу: "Если я не смогу передать свои знания другим, то тогда какой от них смысл?". Я придерживаюсь того-же мнения.

falcon 18.12.2010 21:24

Ответ: Undefined reference to...
 

Цитата:

Я придерживаюсь того-же мнения.
да ради бога! )
я лично тоже категорически поддерживаю это мнение!
Но у тебя (на мой взгляд) это мнение исказилось и превратилось в паранойю.
Передавать свои знания - нужно, да. Но это занятие должно быть полезным. От того, что на новичок получит ответ на очень тривиальный вопрос, пользы не получит ни спрашивающий, ни отвечающий.
Это равносильно просьбы кода, ради копипасты.
На тривиальные вопросы новичок должен находить ответы сам. Находить в литературе или в гугле.
Когда тебя спрашивают "почему компилятор ругается, когда я объявляю массив размером i (где i не const)"
намного лучше послать его читать книжки, в которых авторы намного лучше тебя ответили на этот вопрос, нежели предоставить пример с выделением динамической памяти..
глядишь спрашивающий ещё чего-нибудь полезного из книжки выцепит.
Зря что ли Страуструп, Эккель, Либерти и другие авторы книжки писали?

pax 18.12.2010 21:49

Ответ: Undefined reference to...
 
Цитата:

Сообщение от falcon (Сообщение 172375)
Но у тебя (на мой взгляд) это мнение исказилось и превратилось в паранойю.

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

UPD: Посылая новичка гуглить куда он попадает? На такие же форумы.

falcon 18.12.2010 23:15

Ответ: Undefined reference to...
 

Цитата:

почему они терпят то, что больше половины аудитории их не слушает?
им за это платят.
терпеть ничего не надо.
слушают или нет преподавателя вообще не волнует.

Цитата:

Посылая новичка гуглить куда он попадает? На такие же форумы.
какой запрос должен вбить новичок в гугль, что бы узнать как решить проблему аналогичную проблеме Павла?
Цитата:

Что я натворил не так, исправьте меня лучше щас, а то дальше будет хуже
??

pax, вроде взрослый дядя. Зачем цепляешься к отдельным фразам из текста?
я пытался донести то, что на тривиальные вопросы нужно учиться искать ответы самому. Лучше в литературе. Не менее взрослые и умные дяди свои знания через книжки передают.
На форумах можно увидеть обсуждение какой-либо проблемы. Полезно гуглить, что бы узнать мнения профессионалов касательно какой-то проблемы (с неоднозначным решением). Узнать взгляды на различные методы реализации чего-либо, почитать обсуждение какого-либо метода.

может есть резон обсудить это отдельно?)
в аське, или хотя бы в другом разделе?)
или тема битая, и лучше прекратить флуд, оставшись при своём мнении?
to Randomize

вот уж не надо ><
беда в том, что C++ не из тех языков, на которых можно сесть и тупо начать писать, без понимания "как это работает".
У нас в инсте одну дисциплину ведёт молодой прогер Java. Достаточно опытный такой прогер (для своего возраста), авторитетный.. в проектах серьёзных участвует. Да вот спросил я его, по поводу динамического и статического полиморфизма.. А он и знать не знает, что это. Видать сидя на Java можно мало чего знать, но при этом добавиться отличных оптимальных результатов.
К C++ подход другой нужен. Тонна литературы, много практики.. Очень полезна профессиональная практика, что бы кто-то инспектировал код, что бы знать, как организуются настоящие проекты. Этот язык так многогранен, что изучать его можно очень долгое время..
Хорошей информации по языку и библиотеке - тонны. Просто язык не по статьям учить нужно...


Часовой пояс GMT +4, время: 08:03.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot