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

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

Войти
Регистрация
Восстановить пароль
 
RAFA91
Заблокирован
#1

Копирование при полиморфизме - C++

09.07.2015, 17:16. Просмотров 283. Ответов 14
Метки нет (Все метки)

Всем доброго дня !

Почему при полиморфизме вызывается конструктор копировщик только базового класса

(строка 70) ? Получаю ошибку.

Мне нужна полноценная копия.

Заранее спасибо !!!

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
#include <stdio.h>
#include <conio.h>
#include<iostream>
 
using namespace std;
 
class Mammal
 
{
 
public:
 
    Mammal() : itsAge(1) {printf("\nKONSTRUKTOR Mammal %p\n",this);}
 
    Mammal(int Age) : itsAge(Age) {printf("\nKONSTRUKTOR Mammal 2 %p\n",this);}
 
    virtual ~Mammal() {printf("\nDESTRUKTOR Mammal %p\n",this);}
 
    Mammal(const Mammal & rhs);
 
    virtual void Speak() const {printf("\nMammal speak! %p\n",this);}
 
    int GetAge() const {printf("\nMammal GetAge() %p\n",this); return itsAge;}
 
protected:
 
    int itsAge;
};
 
Mammal :: Mammal(const Mammal & rhs) : itsAge(rhs. GetAge())
 
{printf("\nKONSTRUKTOR COPY Mammal this = %p &rhs = %p\n",this,&rhs);}
 
class Dog : public Mammal
 
{
 
public:
 
    Dog() {printf("\nKONSTRUKTOR Dog %p\n",this);}
 
    Dog(int Age) : Mammal(Age) {printf("\nKONSTRUKTOR Dog 2 %p\n",this);}
 
    virtual ~Dog() {printf("\nDESTRUKTOR Dog %p\n",this);}
 
    Dog(const Dog & rhs);
 
    void Speak() const {printf("\nWoof! %p\n",this);}
};
 
Dog :: Dog(const Dog & rhs) : Mammal(rhs)
 
{printf("\nKONSTRUKTOR COPY Dog this = %p &rhs = %p\n",this,&rhs);}
 
int main()
 
{
     Mammal * ptr = new Dog(45);
 
    printf("\n*** ptr = %p\n",ptr);
 
    printf("\n*** Age = %d\n",ptr->GetAge());
 
        Mammal * A = new Mammal(675);
 
     printf("\n*** A = %p\n",A);
 
     printf("\n*** Age = %d\n",A->GetAge());
 
     Mammal * B  = new Dog(*ptr);
 
    getch();
 
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.07.2015, 17:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Копирование при полиморфизме (C++):

Присваивание при полиморфизме - C++
Здравствуйте, помогите, пожалуйста) Имеем класс A и унаследованный от него B. Если попытаться присвоить один объект типа B, который...

Реализация операторов при полиморфизме - C++
Всем доброго времени суток ! Подскажите пожалуйста как реализовать операторы при полиморфизме, а именно: operator + () operator...

О полиморфизме - C++
проблема с полиморфизмом следующая. Создаю массив указателей на базовый класс, далее заполняю несколько первых ячеек массива ,НО делаю это...

Копирование элементов при push_back deque - C++
Доброго времени суток, форумчане. Появилась проблема при создании скрипта, который работает с файлом. Необходимо сделать топ часто...

Лишние символы при копирование текстового файла - C++
не могу понять почему при копировании текстового файла у меня вставляются в конец куча лишних символов, причем чем больше файл тем больше...

Как сделать автоматическое копирование данных при их изменении? - C++
Я не люблю C++, но вынужден программировать на нем. До этого я пользовался языком, в котором нет многих проблем (или возможностей, смотря с...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
09.07.2015, 17:26 #2
RAFA91, и что, вот это в примере
C++
1
     Mammal * B  = new Dog(*ptr);
компилируется?

Добавлено через 2 минуты
RAFA91, полноценную копию можно сделать так:
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
77
78
79
80
#include <stdio.h>
#include <iostream>
 
using namespace std;
 
class Mammal
{
public:
 
    Mammal() : itsAge(1) {printf("\nKONSTRUKTOR Mammal %p\n",this);}
 
    Mammal(int Age) : itsAge(Age) {printf("\nKONSTRUKTOR Mammal 2 %p\n",this);}
 
    virtual ~Mammal() {printf("\nDESTRUKTOR Mammal %p\n",this);}
 
    Mammal(const Mammal & rhs);
 
    virtual void Speak() const {printf("\nMammal speak! %p\n",this);}
 
    int GetAge() const {printf("\nMammal GetAge() %p\n",this); return itsAge;}
 
    
    virtual Mammal * clone() const
    {
        return new Mammal(*this);
    }
    
protected:
 
    int itsAge;
};
 
Mammal :: Mammal(const Mammal & rhs) : itsAge(rhs. GetAge())
 
{printf("\nKONSTRUKTOR COPY Mammal this = %p &rhs = %p\n",this,&rhs);}
 
class Dog : public Mammal
 
{
 
public:
 
    Dog() {printf("\nKONSTRUKTOR Dog %p\n",this);}
 
    Dog(int Age) : Mammal(Age) {printf("\nKONSTRUKTOR Dog 2 %p\n",this);}
 
    virtual ~Dog() {printf("\nDESTRUKTOR Dog %p\n",this);}
 
    Dog(const Dog & rhs);
 
    void Speak() const {printf("\nWoof! %p\n",this);}
    
    virtual Dog * clone() const
    {
        return new Dog(*this);
    }
};
 
Dog :: Dog(const Dog & rhs) : Mammal(rhs)
 
{printf("\nKONSTRUKTOR COPY Dog this = %p &rhs = %p\n",this,&rhs);}
 
int main()
{
     Mammal * ptr = new Dog(45);
 
     printf("\n*** ptr = %p\n",ptr);
 
     printf("\n*** Age = %d\n",ptr->GetAge());
 
     Mammal * A = new Mammal(675);
 
     printf("\n*** A = %p\n",A);
 
     printf("\n*** Age = %d\n",A->GetAge());
 
     Mammal * B  = ptr->clone(); // создается копия *ptr
 
     return 0;
}
RAFA91
Заблокирован
10.07.2015, 12:51  [ТС] #3
DrOffset благодарю Вас за клонирование моего кода !

Только меня смущает эта запись (((

C++
1
virtual Dog * clone() const
может должно быть так ?

C++
1
2
3
4
5
virtual Mammal * clone() const 
 
{
        return new Dog(*this);
    }
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
10.07.2015, 13:24 #4
Цитата Сообщение от RAFA91 Посмотреть сообщение
DrOffset благодарю Вас за клонирование моего кода !
Это что, сарказм?
Цитата Сообщение от RAFA91 Посмотреть сообщение
Только меня смущает эта запись (((
Такое допускается, если типы возвращаемого значения ковариантны.
RAFA91
Заблокирован
10.07.2015, 15:05  [ТС] #5
Цитата Сообщение от DrOffset Посмотреть сообщение
Такое допускается, если типы возвращаемого значения ковариантны.
вот Вы в базовом классе указали

C++
1
 virtual Mammal * clone() const
следовательно и в производном должно быть что-то подобное с такой-же сигнатурой .

а иначе тогда какой полиморфизм будет.

хотя может что-то я не дочитал. )))
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
10.07.2015, 15:58 #6
Цитата Сообщение от RAFA91 Посмотреть сообщение
хотя может что-то я не дочитал.
Так может стоит дочитать, а не спорить со мной?

Добавлено через 2 минуты
Ну хоть бы даже здесь.
RAFA91
Заблокирован
10.07.2015, 16:05  [ТС] #7
При такой записи получаю ошибку (строка 58)

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <stdio.h>
#include <conio.h>
#include<iostream>
 
using namespace std;
 
class Mammal
 
{
 
public:
 
    Mammal() : itsAge(1) {printf("\nKONSTRUKTOR Mammal %p\n",this);}
 
    Mammal(int Age) : itsAge(Age) {printf("\nKONSTRUKTOR Mammal 2 %p\n",this);}
 
    virtual ~Mammal() {printf("\nDESTRUKTOR Mammal %p\n",this);}
 
    Mammal(const Mammal & rhs);
 
    virtual void Speak() const {printf("\nMammal speak! %p\n",this);}
 
    int GetAge() const {printf("\nMammal GetAge() %p\n",this); return itsAge;}
 
    virtual Mammal * clone() const
 
    {
        printf("\nMammal Clone() %p\n",this); 
 
        return new Mammal(*this);
    }
 
protected:
 
    int itsAge;
};
 
Mammal :: Mammal(const Mammal & rhs) : itsAge(rhs. GetAge())
 
{printf("\nKONSTRUKTOR COPY Mammal this = %p &rhs = %p\n",this,&rhs);}
 
class Dog : public Mammal
 
{
 
public:
 
    Dog() {printf("\nKONSTRUKTOR Dog %p\n",this);}
 
    Dog(int Age) : Mammal(Age) {printf("\nKONSTRUKTOR Dog 2 %p\n",this);}
 
    virtual ~Dog() {printf("\nDESTRUKTOR Dog %p\n",this);}
 
    Dog(const Dog & rhs);
 
    void Speak() const {printf("\nWoof! %p\n",this);}
 
     virtual Dog * clone() const
    {
        return new Dog(*this);
    }
};
 
Dog :: Dog(const Dog & rhs) : Mammal(rhs)
 
{printf("\nKONSTRUKTOR COPY Dog this = %p &rhs = %p\n",this,&rhs);}
 
 
 
int main()
 
{
    Mammal *ptr;
 
    
    printf("\n*****************\n");
 
    ptr = new Dog(45);
 
    printf("\n*** ptr = %p\n",ptr);
 
    printf("\n*** Age = %d\n",ptr->GetAge());
 
    Mammal * A = ptr -> clone();
 
     printf("\n*** A = %p\n",A);
 
     printf("\n*** Age = %d\n",A->GetAge());
 
    getch();
 
    return 0;
}
--------------------Configuration: clone - Win32 Debug--------------------
Compiling...
clone.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\clone\clone.cpp(59) : error C2555: 'Dog::clone' : overriding virtual function differs from 'Mammal::clone' only by return type or calling convention
C:\Program Files\Microsoft Visual Studio\MyProjects\clone\clone.cpp(9) : see declaration of 'Mammal'
Error executing cl.exe.

clone.exe - 1 error(s), 0 warning(s)
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
10.07.2015, 16:12 #8
Цитата Сообщение от RAFA91 Посмотреть сообщение
При такой записи получаю ошибку (строка 58)
Тебе 1000 раз тут уже говорили, что компилятор из VC6 - это очень старый компилятор и что он не поддерживает стандарт С++ в должной мере. Так что будь готов, что еще много какого корректного кода не будет в нем работать. Просто помни об этом всегда, если хочешь на нем оставаться.
RAFA91
Заблокирован
10.07.2015, 16:27  [ТС] #9
Большое спасибо за разьяснение.

Может в новом стандарте все иначе.

http://ideone.com/3YmV4D

только в чем смысл от такой записи в новом стандарте

C++
1
virtual Dog * clone() const
???
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
10.07.2015, 16:33 #10
Цитата Сообщение от RAFA91 Посмотреть сообщение
Может в новом стандарте все иначе.
В любом стандарте это было. Первый стандарт вышел в 1998 году. И там это было. Просто в Студии 6 этого нет.

Цитата Сообщение от RAFA91 Посмотреть сообщение
только в чем смысл от такой записи
Если мы сразу работаем с объектом типа Dog, то сможем получить его копию по указателю того же типа, а не приведенного к базе. Зачем нам терять информацию о типе, если можно этого не делать?
C++
1
2
3
4
5
6
7
8
Dog * dog = new Dog;
 
Dog * copy = dog->clone(); // это сработает, если определить clone как я показал
 
// Если сделать вовращаемый тип Mammal *
// то писать можно будет только так:
 
Mammal * copy = dog->clone(); // и здесь мы потеряли статическую информацию о типе копии.
Я не говорю, что это всегда плохо (или что это вообще плохо). Но иногда это может быть важно.
RAFA91
Заблокирован
10.07.2015, 16:59  [ТС] #11
просто мне интересен тот факт , что

C++
1
2
3
4
virtual Dog * clone() const
    {
        return new Dog(*this);
    }
возвращает указатель типа Dog указателю типа
C++
1
 Mammal * A = ptr -> clone();
без всяких жу-жу-жу. хотя в моем учебнике сказанно о четком контролле за типами обьектов в с++.
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
10.07.2015, 17:10 #12
Цитата Сообщение от RAFA91 Посмотреть сообщение
хотя в моем учебнике сказанно о четком контролле за типами обьектов в с++
Про приведение типов родственных сущностей не сказано? Не верю

К тому же в данном случае никакого приведения вообще нет. ptr - это Mammal *, метод clone у Mammal в возвращает Mammal *.
RAFA91
Заблокирован
11.07.2015, 13:08  [ТС] #13
Цитата Сообщение от DrOffset Посмотреть сообщение
Про приведение типов родственных сущностей не сказано? Не верю
сказанно про приведение типов с помощью
C++
1
dynamic_cast
но лучше этим пренебречь.
DrOffset
7092 / 4233 / 950
Регистрация: 30.01.2014
Сообщений: 7,008
11.07.2015, 14:12 #14
Цитата Сообщение от RAFA91 Посмотреть сообщение
сказанно про приведение типов с помощью
Это явное приведение. Мы ведем речь про неявное.
RAFA91
Заблокирован
11.07.2015, 15:49  [ТС] #15
Спасибо Вам за помощь - буду думать !
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2015, 15:49
Привет! Вот еще темы с ответами:

Копирование строки. При вводе пробела программа пропускает последующий ввод данных - C++
char st, st1; int k, m, i, j; system(&quot;cls&quot;); cout &lt;&lt;&quot;Введите строку&quot;&lt;&lt;endl; cin &gt;&gt;st; cout &lt;&lt;&quot;Введите номер символа,...

Избыточное копирование объекта при реализации оператора умножения и оператора присваивания - C++
Есть класс работы с матрицами. Есть операция умножения матриц, описанная как оператор класса. В данном коротком примере я просто моделирую...

Excel. Копирование столбца, при заполнении 22-й строки продолжить копирование в соседний столбец - VBA
Всем привет. Задача: Есть таблица Excel, заполнены 2 столбца, из них первый - порядковые номера, второй - числа. Нужно: - провести...

Копирование при условии - C++ Builder
Люди добрые, нужна ваша помощь) В общем в списке ListBox есть 4 пункта: Русские буквы, латинские, цифры и знаки препинания. При выборе...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.07.2015, 15:49
Ответ Создать тему
Опции темы

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