crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Наследник абстрактного класса не наследуется..
Berg
  опции профиля:
сообщение 5.7.2013, 0:46
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 5.7.2013
Пользователь №: 3875

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем привет! Помогите решить проблему. Есть абстрактный класс,от которого наследуется потомок. Никак не могу разобраться с деструкторами

Class.h
class Class1
{
public:
    virtual ~Class1() = 0;
    virtual void started() = 0;
}

Class1::~Class1(){}


ExClass.h
#include "Class.h"
class ExClass1 : Class1
{
public:
    void started()
    {
        qDebug () << "Ex started";
    }
    ~ExClass1(){}
};


Вызов started()
mainwindow.cpp
ExClass ExCl;
ExCl.started();


Компилятор ругается
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\Class.h:29: ошибка: first defined here
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\debug\mainwindow.o:-1: In function `~Class1':
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\Class.h:29: multiple definition of Class1::~Class1()'

Заранее спасибо за ответы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.7.2013, 4:24
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Berg @ 5.7.2013, 2:46) *
Class.h:29: ошибка: first defined here
и где эта строка, почему не показываешь соответствующее место в коде?


Цитата(Berg @ 5.7.2013, 2:46) *
class ExClass1 : Class1
почему не указан тип наследования (public, private, ...)?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 5.7.2013, 8:57
Сообщение #3


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


ты объявил чистый виртуальный деструктор
virtual ~Class1() = 0;

и тут же реализацию
Class1::~Class1(){}

понятно, что компилятор ругается
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Berg
  опции профиля:
сообщение 5.7.2013, 9:14
Сообщение #4


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 5.7.2013
Пользователь №: 3875

Спасибо сказали: 0 раз(а)




Репутация:   0  


Забыл, когда писал сообщение
#include "Class.h"
class ExClass1 : public Class1
{...

Ошибка выскакивает на стоке
Class1::~Class1(){}


Я ведь определил деструктор за пределами класса. Или определять надо в другом файле?

Если добавить реализацию деструктора в файл ExClass.h, то те же ошибки на строке
Class1::~Class1(){}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 5.7.2013, 9:21
Сообщение #5


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


1. реализация НИКОГДА не должна быть в заголовочном файле. только в cpp.
2. у абстрактного метода (а также конструктора или деструктора) не может быть никакой реализации в принципе.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 5.7.2013, 9:22
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Berg, убери вообще строку
Class1::~Class1(){}

а после закрывающей фигурной скобки класса поставь ;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Berg
  опции профиля:
сообщение 5.7.2013, 20:48
Сообщение #7


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 5.7.2013
Пользователь №: 3875

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем спасибо за ответы!
Проблему решил (по крайней мере компилятор не ругается и все корректно работает) прописав реализацию в mainwindow.cpp.

Если убрать строку
Class1::~Class1(){}

компилятор ругается на строчку
~ExClass1(){}
так:
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\ExClass.h:37: ошибка: undefined reference to `Class1::~Class1(){}
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\ExClass.h:37: ошибка: undefined reference to `Class1::~Class1(){}
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\ExClass.h:37: ошибка: undefined reference to `Class1::~Class1(){}
D:\MyProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK_________\..\MyProject\\ExClass.h:37: ошибка: undefined reference to `Class1::~Class1(){}
:-1: ошибка: collect2: ld returned 1 exit status
'

Когда гуглил решение проблемы, нашел фрагмент книги "Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ", автор Майерс Скотт
http://www.e-reading-lib.com/chapter.php/1...ovanie_CPP.html

Цитата
class AWOV { // AWOV = “Abstract w/o Virtuals”
public:
virtual ~AWOV() = 0; // объявление чисто виртуального
}; // деструктора

Этот класс включает в себя чисто виртуальную функцию, поэтому он абстрактный. А раз в нем объявлен виртуальный деструктор, то можно не беспокоиться о том, что деструкторы базовых классов не будут вызваны. Однако есть одна тонкость: вы должны предоставить определение чисто виртуального деструктора:

AWOV::~AWOV(){}; // определение чисто виртуального деструктора

Дело в том, что сначала всегда вызывается деструктор «самого производного» класса (то есть находящегося на нижней ступени иерархии наследования), а затем деструкторы каждого базового класса. Компилятор сгенерирует вызов ~AWOV из деструкторов производных от него классов, а значит, вы должны позаботиться о его реализации. Если этого не сделать, компоновщик будет недоволен.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 8.7.2013, 9:42
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


так ты его предоставь ))

class Class1
{
public:
    virtual ~Class1() {};
    ...
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Авварон
  опции профиля:
сообщение 8.7.2013, 22:02
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 99
Регистрация: 26.4.2009
Пользователь №: 709

Спасибо сказали: 14 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 5.7.2013, 8:57) *
ты объявил чистый виртуальный деструктор
virtual ~Class1() = 0;

и тут же реализацию
Class1::~Class1(){}

понятно, что компилятор ругается

Цитата(Iron Bug @ 5.7.2013, 9:21) *
1. реализация НИКОГДА не должна быть в заголовочном файле. только в cpp.
2. у абстрактного метода (а также конструктора или деструктора) не может быть никакой реализации в принципе.



У абстрактного метода может быть реализация. Валидный код:

// .h
Class c
{
public:
    virtual void f() = 0;
}
// .cpp
void Class::f() {}


Сообщение отредактировал Авварон - 8.7.2013, 22:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 9.7.2013, 6:44
Сообщение #10


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Авварон @ 9.7.2013, 1:02) *
Валидный код:

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


Сообщение отредактировал Iron Bug - 9.7.2013, 6:44
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 11:50