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

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

Войти
Регистрация
Восстановить пароль
 
 
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
#1

Виртуальные функции. - C++

27.07.2010, 15:26. Просмотров 834. Ответов 18
Метки нет (Все метки)

Приветствую всех. Дана такая программа (на самом деле она больше и сложнее, но структура и проблема те же):

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
#include <iostream>
using namespace std;
 
class x1
    {
        public:
            virtual void show()
                {
                    cout << "1\n";
                }
    };
class x2 : public x1
    {
        public:
            void show()
                {
                    cout << "2\n";
                }
    };
 
class x3 : public x2
    {
        public:
            void show()
                {
                    cout << "3\n";
                }
    };
 
int main()
    {
        x1 *p[3];
 
        p[0] = &x1();
        p[1] = &x2();
        p[2] = &x3();
 
 
        for(int i = 0; i < 3; i++)
            {
                p[i]->show();
            }
        return 0;
    }
По идее она должна вывести 1 2 3 (на разных строках) но выводит 3 3 3... Вообще бред. Но если записать так

C++
1
2
3
4
5
6
p[0] = &x1();
p[0]->show();
p[1] = &x2();
p[1]->show();
p[2] = &x3();
p[2]->show();

то все ок. Я даже глупо переписал пример из самоучителя ! эффекта ноль. Теперь грешу на компилятор... Так в чем же дело...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.07.2010, 15:26     Виртуальные функции.
Посмотрите здесь:

виртуальные функции - C++
Здравствуйте.Перечитал различные статьи,но не могу до конца вникнуть в смысл использования виртуальных функций.Для взаимного понимания...

Виртуальные функции - C++
Пожалуйста, подскажите как быть: class Circles; class Rectangs; class Snake { public: Circles *drr; void start1(); ...

Виртуальные функции С++ - C++
Задача: В классе хранится целое, и определяется виртуальная функция shownum(). Создать 2 производных класса, наследующие класс num. В...

Виртуальные функции в С++ - C++
Здравствуйт. Помогите осмыслить доконца вирт. ф-ции. После прочтения источников я собрал определенную картину: Вирт функции...

Виртуальные функции - C++
Помогите пожалуйста написать задачу, никак не могу разобраться. Создайте класс Matr, определите в нем виртуальную функцию-член...

Виртуальные функции - C++
Какие происходят изменения, когда в классе объявляем одну или несколько функций виртуальными? Вот, например, если в SuperClass перед...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
rangerx
1932 / 1541 / 141
Регистрация: 31.05.2009
Сообщений: 2,911
27.07.2010, 15:40     Виртуальные функции. #2
Вы присваиваете указателям адреса временных объектов. Когда дело доходит до цикла, этих объектов уже не существует.
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
27.07.2010, 15:47  [ТС]     Виртуальные функции. #3
Но почему тогда выводится 3 3 3, а не еще что-нибудь...
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
27.07.2010, 16:04     Виртуальные функции. #4
Эм. Выводит 1, 2, 3 по вашему коду.
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
27.07.2010, 16:08  [ТС]     Виртуальные функции. #5
Что за компилятор??

Запустите кто-нибудь эту прогу и скажите что у вас выводит...
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
27.07.2010, 16:10     Виртуальные функции. #6
maxibon, IDE Visual Studio 2005.
Nameless One
Эксперт С++
5769 / 3418 / 255
Регистрация: 08.02.2010
Сообщений: 7,446
27.07.2010, 16:12     Виртуальные функции. #7
Цитата Сообщение от Lavroff Посмотреть сообщение
Эм. Выводит 1, 2, 3 по вашему коду.
Аналогично. Может быть, приведешь уже весь код?
А вообще rangerx прав, и нужно бы сделать так (особенно, если классы у тебя имеют данные-члены):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    x1 *p[3];
    p[0] = new x1;
    p[1] = new x2;
    p[2] = new x3;
 
    for(int i = 0; i < 3; i++)
        p[i]->show();
 
    for(size_t i = 0; i < 3; ++i)
        delete p[i];
    system("pause");
    return 0;
}
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
27.07.2010, 16:14  [ТС]     Виртуальные функции. #8
Цитата Сообщение от Lavroff Посмотреть сообщение
maxibon, IDE Visual Studio 2005.
это не компилятор а среда разработки// ладно, попробую зпускать show без цикла, а сразу после присваивания ему объекта. Всеи кто ответил спасибо1
ForEveR
27.07.2010, 16:16
  #9

Не по теме:

maxibon, А IDE я просто так перед названием написал да?) Я знаю, что это среда разработки)

CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,365
27.07.2010, 16:19     Виртуальные функции. #10
Цитата Сообщение от maxibon Посмотреть сообщение
Но почему тогда выводится 3 3 3, а не еще что-нибудь...
А может выводить хоть "Hello, World!", если заблагорассудится. Временных объектов уже не существует, а обращение (по указателю) к несуществующему объекту - это UB. Как именно это UB проявится - это Б.Г. его знает....
Nameless One
Эксперт С++
5769 / 3418 / 255
Регистрация: 08.02.2010
Сообщений: 7,446
27.07.2010, 16:29     Виртуальные функции. #11
Цитата Сообщение от maxibon Посмотреть сообщение
ладно, попробую зпускать show без цикла, а сразу после присваивания ему объекта. Всеи кто ответил спасибо1
Это ничего не изменит, т.к. ты инициализируешь указатели временными объектами, которые уничтожаются сразу после инициализации.
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
27.07.2010, 16:36  [ТС]     Виртуальные функции. #12
Цитата Сообщение от Nameless One Посмотреть сообщение
Это ничего не изменит, т.к. ты инициализируешь указатели временными объектами, которые уничтожаются сразу после инициализации.
Самое интересное что изменит. Я ж еще этот вариант

C++
1
2
3
4
5
6
p[0] = &x1();
p[0]->show();
p[1] = &x2();
p[1]->show();
p[2] = &x3();
p[2]->show();
в самом первом посте написал. Ну и потом как ты объяснишь то что этот вариант

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
    {
        x1 *p[3];
 
        p[0] = &x1();
        p[1] = &x2();
        p[2] = &x3();
 
 
        for(int i = 0; i < 3; i++)
            {
                p[i]->show();
            }
        return 0;
    }
у некоторых работает?
Nameless One
Эксперт С++
5769 / 3418 / 255
Регистрация: 08.02.2010
Сообщений: 7,446
27.07.2010, 16:45     Виртуальные функции. #13
Как сказал CheshireCat, поведение твоей программы не определено, о чем уже говорит то, что не у всех твой вариант работает. Согласись, правильно написанная программа должна работать у всех и всегда.
Пойми, что так делать - неправильно. Если ты будешь использовать в дальнейшем такой "трюк", то неприменно столкнешься с ошибками.

Цитата Сообщение от maxibon Посмотреть сообщение
Самое интересное что изменит
Опять-таки повторюсь:
Цитата Сообщение от Nameless One Посмотреть сообщение
ты инициализируешь указатели временными объектами, которые уничтожаются сразу после инициализации
, поэтому не имеет значения, когда ты будешь вызывать свою функцию. Потому, что:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
    {
        x1 *p[3];
 
        p[0] = &x1();
        p[1] = &x2();//Здесь УЖЕ не существует объекта, адрес которого ты присвоил p[0]
        p[2] = &x3();
 
 
        for(int i = 0; i < 3; i++)
            {
                p[i]->show();//Как и не существует этого объекта здесь
            }
        return 0;
    }
В общем, дело твое, делай как хочешь, но мы тебя предупредили...
Evg
Эксперт CАвтор FAQ
17547 / 5785 / 370
Регистрация: 30.03.2009
Сообщений: 15,937
Записей в блоге: 26
27.07.2010, 21:26     Виртуальные функции. #14
А поясните, пожалуйста, что означает конструкция

C++
1
p[0] = &x1();
конструктор вроде бы как нельзя вызывать напрямую
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.07.2010, 06:45     Виртуальные функции.
Еще ссылки по теме:

Виртуальные функции - C++
Если в базовом классе А есть виртуальная функция show() перегруженная, то есть имеется три разные версии этой функции. Есть класс Б...

Виртуальные функции - C++
Пытаюсь понять что это такое но не понимаю. Может есть какие то болие понятные примеры , а то то что я смотрел не дало результата. ...

Виртуальные функции - C++
Объясните, для чего необходимы виртуальные функции. Где их рационально использовать. P.S. Если есть ссылки на толковые материалы - не...

Виртуальные функции - C++
Не работает код. Проблема в виртуальной функции. Как это можно исправить? #include &lt;iostream&gt; class Convert { protected: ...


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

Или воспользуйтесь поиском по форуму:
Nameless One
Эксперт С++
5769 / 3418 / 255
Регистрация: 08.02.2010
Сообщений: 7,446
28.07.2010, 06:45     Виртуальные функции. #15
Evg, здесь создается временный (безымянный) объект типа x1 (при этом вызывается конструктор по умолчанию для временного объекта), и его адрес присваивается указателю на x1. Но соль в том, что после присваивания адреса временный объект уничтожается, и указатель хранит адрес уже не существующего объекта.
Вот пример того, как можно было бы использовать временные объекты:
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
#include <iostream>
#include <string>
 
#define print(A) std::cout << #A " = \"" << A << "\"" << std::endl
 
class abc
{
    std::string msg;
public:
    abc()
        : msg("Hello, World")
    {}
    abc(const abc& rhs)
        : msg(rhs.msg)
    {}
    friend std::ostream& operator << (std::ostream& os, const abc& rhs)
    {
        os << rhs.msg;
        return os;
    }
};
 
int main()
{
    std::string string1 = std::string("test");
    std::string string2 = std::string(string1);
    int x = int();
    abc a = abc();
 
    print(string1);
    print(string2);
    print(x);
    print(a);
    system("pause");
    return EXIT_SUCCESS;
}
Yandex
Объявления
28.07.2010, 06:45     Виртуальные функции.
Ответ Создать тему
Опции темы

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