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

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

Восстановить пароль Регистрация
 
RAFA91
Заблокирован
09.07.2015, 17:16     Копирование при полиморфизме #1
Всем доброго дня !

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

(строка 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;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
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
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
10.07.2015, 13:24     Копирование при полиморфизме #4
Цитата Сообщение от RAFA91 Посмотреть сообщение
DrOffset благодарю Вас за клонирование моего кода !
Это что, сарказм?
Цитата Сообщение от RAFA91 Посмотреть сообщение
Только меня смущает эта запись (((
Такое допускается, если типы возвращаемого значения ковариантны.
RAFA91
Заблокирован
10.07.2015, 15:05  [ТС]     Копирование при полиморфизме #5
Цитата Сообщение от DrOffset Посмотреть сообщение
Такое допускается, если типы возвращаемого значения ковариантны.
вот Вы в базовом классе указали

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

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

хотя может что-то я не дочитал. )))
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
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
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
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
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
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
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
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
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
11.07.2015, 14:12     Копирование при полиморфизме #14
Цитата Сообщение от RAFA91 Посмотреть сообщение
сказанно про приведение типов с помощью
Это явное приведение. Мы ведем речь про неявное.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2015, 15:49     Копирование при полиморфизме
Еще ссылки по теме:

О полиморфизме C++
Копирование строки. При вводе пробела программа пропускает последующий ввод данных C++
Реализация операторов при полиморфизме C++

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

Или воспользуйтесь поиском по форуму:
RAFA91
Заблокирован
11.07.2015, 15:49  [ТС]     Копирование при полиморфизме #15
Спасибо Вам за помощь - буду думать !
Yandex
Объявления
11.07.2015, 15:49     Копирование при полиморфизме
Ответ Создать тему
Опции темы

Текущее время: 08:45. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru