Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.95
jemper
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
#1

[linker error] undefined reference to 'vtable for Car' - C++

15.01.2010, 18:16. Просмотров 2337. Ответов 13
Метки нет (Все метки)

доброго времени вам. помогите, пожалуйста, с задачей разобраться. хочу сделать пример на паттерн "абстрактная фабрика". фабрика собирает афтомобили.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <cstdlib>
#include <iostream>
#include <new>
#include <cstring>
 
using namespace std;
 
 
class Engine 
{ 
public: 
  virtual void setSpeedLimit(int kmph); 
  virtual void addOil(float amount); 
  
}; 
class Wheel 
{ 
  float mRadius; 
public: 
  Wheel(float radius) { mRadius = radius; } 
  virtual float getRadius() const {return mRadius;} 
}; 
 
 
class Car 
{ 
public: 
  virtual const char* getName() = 0; 
  virtual void setEngine(Engine* engine); 
  virtual void setWheels(Wheel* FR, Wheel* FL, Wheel* BR, Wheel* BL);
 // virtual void setFrontWheels(Wheel* FR, Wheel* FL); 
 // virtual void setBackWheels(Wheel* BR, Wheel* BL); 
 
};
class AbstractCarFactory  //создаем абстрактный класс, с единственным предназначением- быть 
                         //родителем для других классов.
{ 
public: 
  virtual Car* createCar() = 0;
  virtual Engine* createEngine() = 0;
  virtual Wheel* createWheel() = 0;
};
class CarBMW5 : public Car 
{ 
public: 
   const char* getName() {return "BMW5";} 
   void setEngine(Engine* engine) {engine->setSpeedLimit(100); engine->addOil(12.3); } 
   void setWheels(Wheel* FR, Wheel* FL, Wheel* BR, Wheel* BL) {cout<< "колеса";}
};
 
class BMW5CarFactory : public AbstractCarFactory 
{ 
 public: 
  virtual Car* createCar() { return new CarBMW5(); } 
  virtual Engine* createEngine() {return new Engine();} 
  virtual Wheel* createWheel() {return new Wheel(16);} 
 }; 
 
Car* createCar(AbstractCarFactory* carFactory) 
{ 
  Car* car = carFactory->createCar(); 
  Engine* engine = carFactory->createEngine(); 
  car->setEngine(engine); 
  car->setWheels(carFactory->createWheel(), carFactory->createWheel(), carFactory->createWheel(), carFactory->createWheel()); 
  //  код для "сборки" готового автомобиля из частей 
  return car; 
}
 
 
int main(int argc, char *argv[])
{
 CarBMW5 a;  // при попытке создания объекта класса выдает ошибки во время компиляции. если  строку закомментировать - ошибок не выдает.
// BMW5CarFactory b;  
    system("PAUSE");
    return EXIT_SUCCESS;
}
ошибки:
[linker error] undefined reference to 'vtable for Car'
ld returned 1 exit status
C:\Dev-Cpp\Makefile.win [Build Error] [project1.exe] Error 1
если раскомментировать строку "// BMW5CarFactory b; " то добавляет к этим ошибкам еще такую:
[Linker error] undefined reference to `vtable for Engine'
ранних версий компилятора не было, да и других компиляторов вроде нету на компе..
какая может быть причина, подскажите, пожалуйста)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
M128K145
Эксперт С++
8283 / 3502 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
15.01.2010, 19:38     [linker error] undefined reference to 'vtable for Car' #2
C++
1
CarBMW5 *a;
jemper
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 09:12  [ТС]     [linker error] undefined reference to 'vtable for Car' #3
да, я так делал уже. при этом все вроде нормально, но программа падает на выполнении, например, такой команды:
C++
1
а->getName();
и мне интересно, почему нельзя непосредственно создать объект класса CarBMW5? зачем обязательно создавать указатель на объект? в чем ошибка?
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
16.01.2010, 11:34     [linker error] undefined reference to 'vtable for Car' #4
jemper, это у тебя задание в институте или ты для для себя изучаешь?
jemper
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 11:38  [ТС]     [linker error] undefined reference to 'vtable for Car' #5
вообще не понимаю, что это слово "vtable" означает и откуда оно взялось

Добавлено через 1 минуту
да самому разобраться нужно.. но и к институту имеет отношение
ISergey
Maniac
Эксперт С++
1372 / 883 / 52
Регистрация: 02.01.2009
Сообщений: 2,652
Записей в блоге: 1
16.01.2010, 12:00     [linker error] undefined reference to 'vtable for Car' #6
http://ru.wikipedia.org/wiki/Абстрак...проектирования)
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
16.01.2010, 12:49     [linker error] undefined reference to 'vtable for Car' #7
Цитата Сообщение от jemper Посмотреть сообщение
вообще не понимаю, что это слово "vtable" означает и откуда оно взялось
В отличие от Си, язык Си++ является высокоуровневым. Т.е. ты пишешь в исходнике чего-то, а в процессе построения кода компилятор дополнительно рожает ещё целую кучу кода. В данном случае компилятор строит дополнительные таблицы виртуальных функций (слово vtable берётся оттуда)

Цитата Сообщение от jemper Посмотреть сообщение
да самому разобраться нужно.. но и к институту имеет отношение
Я просто спросил к тому, что у тебя классы концептуально неправильно реализованы. Вообще для классов есть понятия "свойство" и "метод". Свойство - это то, что можно хранить в виде данных. Например, если есть класс "фигура круг", то "радиус" - это свойство, ибо его можно хранить в виде данных. А вот "нарисовать" это уже метод, поскольку он требует каких-то действий и его нельзя хранить в виде данных (в нормальном случае)

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
 
class Car 
{ 
private:
  // Название машины. Модификатор const по сути дела означает то, что
  // это поле можно изменить только при создании объекта в конструкторе,
  // после чего это поле модифицировать уже нельзя. Название машины - это
  // такая вещь, которая даётся машине один раз и уже не меняется.
  // Модификатор const дополнительно спасёт нас от внутренних ошибок
  // и при попытке изменить это поле компилятор выругается
  std::string const m_Name;
 
public: 
  // В конструкторе записываем название
  Car (const std::string &name) : m_Name (name) { }
 
  // Метод getName НЕ должен быть виртуальным, т.к. всё разнообразие
  // наследников класса будет записывать имя машины в поле m_Name,
  // при этом метод остаётся единым для всех. Т.е. различие идёт НЕ
  // в реализации метода, а в хранении данных
  const std::string& getName() const { return m_Name; }
};
 
class CarBMW : public Car
{
public:
  // Из нашего конструктора вызываем конструктор базового класса, чтобы
  // задать ему свойство m_Name
  CarBMW () : Car ("BMW") { }
};
 
class CarAudi : public Car
{
public:
  // Аналогично
  CarAudi () : Car ("Audi") { }
};
 
int
main (void)
{
  CarBMW car1;
  CarAudi car2;
 
  std::cout << car1.getName() << endl;
  std::cout << car2.getName() << endl;
}
Колёса должны быть такими же данными. Но в случае с колёсами ситуация немного другая. За время жизни колёса могут меняться (но название остаётся одним и тем же). Поэтому колёса должны быть выполнены так, чтобы их можно было заменять

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Car
{
  ...
private:
  Wheel *m_W1, *m_W2, *m_W3, *m_W4;
public:
  setWheels (Wheel *w1, Wheel *w2, Wheel *w3, Wheel *w4)
  {
    m_W1 = w1;
    m_W2 = w2;
    m_W3 = w3;
    m_W4 = w4;
  }
  getWheel1 () { return m_W1; }
  getWheel2 () { return m_W2; }
  getWheel3 () { return m_W3; }
  getWheel4 () { return m_W4; }
}
В итоге в конечном счёте получается, что на данном уровне тебе виртуальные функции не нужны

Добавлено через 2 минуты
Да, использование string'ов вместо char*, использование модификаторов const, передаче параметров по ссылке (через &) может тебе показаться несколько непонятным. В приницпе, можно переписать и без этого, но если нужно для себя, то лучше приучай себя сразу к тому, что делать по-человечески
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:01     [linker error] undefined reference to 'vtable for Car' #8
Цитата Сообщение от jemper Посмотреть сообщение
да и других компиляторов вроде нету на компе..
онлайн-компилятор
codepad.org
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
16.01.2010, 14:07     [linker error] undefined reference to 'vtable for Car' #9
Кстати, в моём примере колёса в машине хранились по указателю, при этом колёса создавались ЗА пределами класса машины. Это есть опасная конструкция, т.к. в месте создания можно ошибиться и удалить колёса, в результате чего в машине окажутся указатели на удалённые объекты. Более правильно колёса хранить по значению.

По указателю можно хранить только то, что создаётся внутри класса (и, соотвественно, будет удалено внутри класса). Эти указатели по возможности наружу не выдавать, чтобы их кто-то случайно не удалил. Для маленьких программ такие проблемы ищутся быстро, но в больших проектах можно искать очень долго
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:11     [linker error] undefined reference to 'vtable for Car' #10
Цитата Сообщение от Evg Посмотреть сообщение
Более правильно колёса хранить по значению.
нет "более правильного" и "менее правильного". всё зависит от ситуации.

если колёса должны будут существовать после того, как машина будет уничтожена - класс "машина" просто берёт их в аренду, иначе - время жизни этих объектов должно совпадать.
jemper
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 14:22  [ТС]     [linker error] undefined reference to 'vtable for Car' #11
большое спасибо за ответы, сейчас сижу разбираюсь...
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:37     [linker error] undefined reference to 'vtable for Car' #12
Цитата Сообщение от jemper Посмотреть сообщение
сейчас сижу разбираюсь...
здесь хорошо паттерны описаны
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
16.01.2010, 16:23     [linker error] undefined reference to 'vtable for Car' #13
Цитата Сообщение от zim22 Посмотреть сообщение
нет "более правильного" и "менее правильного". всё зависит от ситуации
"Более правильно" или "менее правильно" относилось скорее к технике (стилю) программирования, чем к ООП. С ходу могу написатьпример, который при указанном методе хранения начнёт косячить, хотя идеологически вроде бы всё правильно. Когда один человек пишет одну маленькую программу - соображения о правильности такие. Когда тысяча человек пишут программу, исходники которой исчисляются сотнями мегабайт, соображения будут совсем другие. Причём я очень чётко понимаю, что начинающему это различие объяснить очень сложно (потому как когда-то мне тоже объясняли, но я считал эти объяснения неправильными)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.12.2011, 12:43     [linker error] undefined reference to 'vtable for Car'
Еще ссылки по теме:
Выдает ошибку [Linker error] undefined reference to `WinMain@16' C++
C++ undefined reference to `vtable for
Ошибка [Linker error] undefined reference to `Vector::Vector(int)' C++
C++ Ошибка компиляции единого файла: undefined reference to `vtable for .'
[Linker error] undefined reference to `sterling(int, int, int)' C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17462 / 5700 / 361
Регистрация: 30.03.2009
Сообщений: 15,639
Записей в блоге: 26
24.12.2011, 12:43     [linker error] undefined reference to 'vtable for Car' #14
Для истории более грамотный пример на реализацию наследования:
Создать класс "Студент" и классы "Бюджетный студент" и "Коммерческий студент"
Yandex
Объявления
24.12.2011, 12:43     [linker error] undefined reference to 'vtable for Car'
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru