0 / 0 / 0
Регистрация: 10.05.2021
Сообщений: 4
1

Наследование от класса с виртуальными функциями в сторонней динамической библиотеке

10.05.2021, 05:03. Показов 608. Ответов 5

Есть класс с виртуальными функциями, например, Parent вида:

файл Parent.h:
C++
1
2
3
4
5
6
class Parent
{
public:
  Parent() {}
  virtual ~Parent();
};
файл Parent.cpp:
C++
1
2
3
4
#include "Parent.h"
Parent::~Parent()
{
}
из них строится динамическая библиотека libParent.so

могу ли я в другом своём проекте как-то создать и использовать наследника, например, класс Child вида:

файл Child.h:
C++
1
2
3
4
5
6
7
#include "Parent.h"
class Child : public Parent
{
public:
  Child() {}
  virtual ~Child();
};
файл Child.cpp:
C++
1
2
3
4
5
#include "Child.h"
Child::~Child()
{
}
Child tmp;
и собирается проект Child с помощью CMake, фрагмент CMakeLists.txt:

Код
add_library( # Sets the name of the library.
        parent
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        IMPORTED)
set_target_properties(parent PROPERTIES IMPORTED_LOCATION
        $ENV{PARENT_PATH}/libParent.so)

add_library( # Sets the name of the library.
        child
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        $ENV{CHILD_PATH}/Child.cpp)

target_link_libraries( # Specifies the target library.
        child
        parent)
В результате при построении я получаю ошибку вида:

Код
Child.cpp.o:Child.cpp:typeinfo for Child: error: undefined reference to 'typeinfo for Parent'
Как я понимаю, это происходит потому, что виртуальные функции класса Parent определены в файле Parent.cpp и соответственно находятся только внутри библиотеки libParent.so, а в Parent.h есть только их объявление и в результате при построении проекта Child компилятор не находит необходимые ему определения виртуальных функций родительского класса и выдаёт ошибку.

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

Но что мне можно сделать, если я не хочу менять эту стороннюю библиотеку libParent.so и переносить определения виртуальных функций из cpp в h, а просто хочу воспользоваться её классом Parent с виртуальными функциями в качестве предка для моего класса Child? Возможно ли это в принципе? Может мне нужно каким-то особым образом подключить к проекту Child библиотеку libParent.so, чтобы при построении проекта Child компилятор мог увидеть/использовать определения виртуальных функций внутри библиотеки libParent.so?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.05.2021, 05:03
Ответы с готовыми решениями:

Подключение к проекту на Qt5.7 сторонней динамической библиотеке
Здравствуйте. Возник следующий вопрос с подключением сторонней динамической библиотеке в свой...

Создание класса в динамической библиотеке
Доброго времени суток! Прочел статью в на cyberguru: как написать динамическую библиотеку, и решил...

Работа с виртуальными функциями
Доброго времени суток, форумчани! Помогите мне, пожалуйста, с задачей, у меня просто нет этой темы,...

Проблема с виртуальными функциями
Привет. Столкнулся с небольшой проблемой, касательно виртуальных функций. Стыдно спрашивать, ибо...

5
С чаем беда...
Эксперт CЭксперт С++
9989 / 5341 / 1461
Регистрация: 18.10.2014
Сообщений: 12,854
10.05.2021, 07:25 2
Цитата Сообщение от Elija Посмотреть сообщение
Как я понимаю, это происходит потому, что виртуальные функции класса Parent определены в файле Parent.cpp и соответственно находятся только внутри библиотеки libParent.so, а в Parent.h есть только их объявление и в результате при построении проекта Child компилятор не находит необходимые ему определения виртуальных функций родительского класса и выдаёт ошибку.
Нет, не потому.

Пример который вы привели - он точен? Именно на таком элементарном коде вы получаете такую ошибку?
0
0 / 0 / 0
Регистрация: 10.05.2021
Сообщений: 4
10.05.2021, 07:41  [ТС] 3
TheCalligrapher,
Пример который вы привели - он точен? Именно на таком элементарном коде вы получаете такую ошибку?
Классы на которых изначально возникла проблема сложнее. Но в процессе выяснения причин ошибки, я добавил эти элементарные классы и на них не работает, как я описал. Ну или работает, если перенести определение виртуальных функций из .cpp в .h.
P.S. Я использую Android Studio 4.1.3 + clang++
0
С чаем беда...
Эксперт CЭксперт С++
9989 / 5341 / 1461
Регистрация: 18.10.2014
Сообщений: 12,854
10.05.2021, 18:01 4
Цитата Сообщение от Elija Посмотреть сообщение
P.S. Я использую Android Studio 4.1.3 + clang++
Надо смотреть установки компиляции библиотеки. Включена ли там вообще генерация RTTI, то есть нет ли там какого -fno-rtti в настройках.

Цитата Сообщение от Elija Посмотреть сообщение
я добавил эти элементарные классы
"Добавил" именно в виде новых файлов Parent.h/Parent.cpp или все таки в уже существующие файлы? Если Parent.cpp - отдельный файл, то он вообще участвует в построении библиотеки?
0
Комп_Оратор)
Эксперт по математике/физике
8726 / 4473 / 600
Регистрация: 04.12.2011
Сообщений: 13,361
Записей в блоге: 16
10.05.2021, 18:34 5
Elija, по идее, если это не шаблоны то всё должно слинковаться. Я только не увидел прототипов виртуальных функций (кроме деструктора) в заголовочнике Parent.h. Если их там нет, то и не будет ни чего. Дополните пример. Реализации функций можете оставить в cpp-шниках.
Верно и то, что если определены прототипы (не чисто виртуальных методов) без определения (даже в других файлах типа cpp) то тоже плохо.
0
0 / 0 / 0
Регистрация: 10.05.2021
Сообщений: 4
12.05.2021, 06:25  [ТС] 6
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Надо смотреть установки компиляции библиотеки. Включена ли там вообще генерация RTTI, то есть нет ли там какого -fno-rtti в настройках.
-fno-rtti отсутствует

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"Добавил" именно в виде новых файлов Parent.h/Parent.cpp или все таки в уже существующие файлы? Если Parent.cpp - отдельный файл, то он вообще участвует в построении библиотеки?
Добавил в существующий в проекте файл, чтобы эксперимент был проще. Когда я увидел undefined reference, то первым делом проверил подключение файла к проекту. Он там есть. И функции других классов этого файла находятся внутри библиотеки libParent.so

Добавлено через 9 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
по идее, если это не шаблоны то всё должно слинковаться. Я только не увидел прототипов виртуальных функций (кроме деструктора) в заголовочнике Parent.h. Если их там нет, то и не будет ни чего. Дополните пример. Реализации функций можете оставить в cpp-шниках.
Верно и то, что если определены прототипы (не чисто виртуальных методов) без определения (даже в других файлах типа cpp) то тоже плохо.
Это не шаблоны. Я добавлял и другие виртуальные функции, но для упрощения примера оставил только деструктор. Наличия виртуального деструктора хватает для того поведения, что я описал. Я понимаю, что если есть объявление, но нет определения функции, то и возникает undefined reference. Но это не тот случай. Вернее не тот случай в том смысле, что определения всех функций есть в cpp. Но по какой-то причине линкер их не видит?

Попробую сделать минимальный пример с участием только описанных файлов Parent и Child. Если получится и поведение останется прежним, то выложу тут ссылку на github.

Добавлено через 1 минуту
Добавлено через 2 часа 33 минуты
Цитата Сообщение от Elija Посмотреть сообщение
Попробую сделать минимальный пример с участием только описанных файлов Parent и Child. Если получится и поведение останется прежним, то выложу тут ссылку на github.
Собрал такой элементарный проект и выяснил, что данная ситуация происходит, только когда библиотека libParent.so собирается с помощью ndk-build. Если же у неё поменять сборку на cmake, то всё собирается без проблем. Проект Child всегда собирается через cmake. Буду разбираться уже с системой сборки. Всем спасибо.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.05.2021, 06:25
Помогаю со студенческими работами здесь

Задачка с наследованием и виртуальными функциями
Диаграмма классов на приложенном рисунке. #include <iostream> class IData { public:...

Классы с виртуальными функциями. Class Student
Создать класс Студент со свойствами: ФИО, Факультет, Курс, минималь- ная оценка по экзаменам за...

Неправильный вывод при работе с виртуальными функциями
В общем, учу плюсы по книге Праты. Там есть одно задание по виртуальным функциям. Но дело сейчас не...

Изменения в сторонней библиотеке
Приветствую! Что требуется, чтобы иметь возможность внести изменения в стороннюю библиотеку...

Реализовать абстрактный класс pair c виртуальными арифметическими функциями
Вот задание: Создать абстрактный базовый класс Pair с виртуальными арифметическими операциями....

Создать абстрактный базовый класс с виртуальными функциями - площадь и периметр
Помогите написать,не врублюсь как писать много пропустил (( Задание:Создать абстрактный базовый...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru