Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/19: Рейтинг темы: голосов - 19, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6

[linker error] undefined reference to 'vtable for Car'

15.01.2010, 18:16. Показов 3969. Ответов 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'
ранних версий компилятора не было, да и других компиляторов вроде нету на компе..
какая может быть причина, подскажите, пожалуйста)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.01.2010, 18:16
Ответы с готовыми решениями:

Странная ошибка: [Linker error] undefined reference to `__dyn_tls_init_callback' [Linker error] undefined reference to ld returned 1 exit status
Здравствуйте. Вот недавно начал изучать книгу &quot;С++ для чайников&quot; Стефан Р. Девис 4-е издание. И напоролся на кучу ошибок) Но смог все...

[Linker error] undefined reference to
#include&lt;string.h&gt; #include&lt;stdlib.h&gt; #include&lt;conio.h&gt; #include&lt;stdio.h&gt; #include &lt;math.h&gt; #include&lt;fstream&gt; ...

[Linker Error] undefined reference to
Вызываю так функцию в main'e: #include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &quot;matrix.h&quot; using...

13
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
15.01.2010, 19:38
C++
1
CarBMW5 *a;
0
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 09:12  [ТС]
да, я так делал уже. при этом все вроде нормально, но программа падает на выполнении, например, такой команды:
C++
1
а->getName();
и мне интересно, почему нельзя непосредственно создать объект класса CarBMW5? зачем обязательно создавать указатель на объект? в чем ошибка?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.01.2010, 11:34
jemper, это у тебя задание в институте или ты для для себя изучаешь?
0
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 11:38  [ТС]
вообще не понимаю, что это слово "vtable" означает и откуда оно взялось

Добавлено через 1 минуту
да самому разобраться нужно.. но и к институту имеет отношение
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
16.01.2010, 12:00
http://ru.wikipedia.org/wiki/А... ктирования)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.01.2010, 12:49
Цитата Сообщение от 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, передаче параметров по ссылке (через &) может тебе показаться несколько непонятным. В приницпе, можно переписать и без этого, но если нужно для себя, то лучше приучай себя сразу к тому, что делать по-человечески
1
depict1
 Аватар для zim22
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:01
Цитата Сообщение от jemper Посмотреть сообщение
да и других компиляторов вроде нету на компе..
онлайн-компилятор
codepad.org
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.01.2010, 14:07
Кстати, в моём примере колёса в машине хранились по указателю, при этом колёса создавались ЗА пределами класса машины. Это есть опасная конструкция, т.к. в месте создания можно ошибиться и удалить колёса, в результате чего в машине окажутся указатели на удалённые объекты. Более правильно колёса хранить по значению.

По указателю можно хранить только то, что создаётся внутри класса (и, соотвественно, будет удалено внутри класса). Эти указатели по возможности наружу не выдавать, чтобы их кто-то случайно не удалил. Для маленьких программ такие проблемы ищутся быстро, но в больших проектах можно искать очень долго
0
depict1
 Аватар для zim22
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:11
Цитата Сообщение от Evg Посмотреть сообщение
Более правильно колёса хранить по значению.
нет "более правильного" и "менее правильного". всё зависит от ситуации.

если колёса должны будут существовать после того, как машина будет уничтожена - класс "машина" просто берёт их в аренду, иначе - время жизни этих объектов должно совпадать.
0
0 / 0 / 0
Регистрация: 15.01.2010
Сообщений: 6
16.01.2010, 14:22  [ТС]
большое спасибо за ответы, сейчас сижу разбираюсь...
0
depict1
 Аватар для zim22
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
16.01.2010, 14:37
Цитата Сообщение от jemper Посмотреть сообщение
сейчас сижу разбираюсь...
здесь хорошо паттерны описаны
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.01.2010, 16:23
Цитата Сообщение от zim22 Посмотреть сообщение
нет "более правильного" и "менее правильного". всё зависит от ситуации
"Более правильно" или "менее правильно" относилось скорее к технике (стилю) программирования, чем к ООП. С ходу могу написатьпример, который при указанном методе хранения начнёт косячить, хотя идеологически вроде бы всё правильно. Когда один человек пишет одну маленькую программу - соображения о правильности такие. Когда тысяча человек пишут программу, исходники которой исчисляются сотнями мегабайт, соображения будут совсем другие. Причём я очень чётко понимаю, что начинающему это различие объяснить очень сложно (потому как когда-то мне тоже объясняли, но я считал эти объяснения неправильными)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
24.12.2011, 12:43
Для истории более грамотный пример на реализацию наследования:
Создать класс "Студент" и классы "Бюджетный студент" и "Коммерческий студент"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.12.2011, 12:43
Помогаю со студенческими работами здесь

[Linker error] undefined reference to 'r'
Помогите решить вышеописанную проблему, на переменную s так же ругаеться! #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include...

[Linker Error] undefined reference to `__dyn_tls_init_callback'
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; int SumDigits (int N) { int d, sum = 0; while ( N != 0 ) ...

[Linker Error] undefined reference to `instructions()'
Dev c++ #include &lt;iostream&gt; using namespace std; void instructions(); int main() { instructions(); return 0;} void...

[Linker error] undefined reference to __cpu_features_init
Вот наглядное пособие: ... А что он говорит и что делать, чтобы прога заработала?

Ошибка [Linker error] undefined reference to `__dyn_tls_init_callback'
Вот такие ошибки появляются : Ошибка undefined reference to `__dyn_tls_init_callback' undefined reference to...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru