Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

27.07.2010, 15:26. Просмотров 852. Ответов 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();

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

виртуальные и чисто виртуальные функции - C++
Чем они отличаются?? если можно, с примерами. И как из виртуальной функции сделать чисто виртуальную? #include &lt;iostream&gt; using...

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

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

Виртуальные функции - C++
Здравствуйте, помогите пожалуйста с вопросом: Заданный порожденный класс, содержащий две функции по таким именно именами, как и в...

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

виртуальные функции - C++
сделать какой либо из методов класса виртуальным #include&lt;iostream.h&gt; #include&lt;stdio.h&gt; class chislo { int a; public: ...

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

Запустите кто-нибудь эту прогу и скажите что у вас выводит...
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
27.07.2010, 16:10 #6
maxibon, IDE Visual Studio 2005.
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
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;
}
0
maxibon
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 7
27.07.2010, 16:14  [ТС] #8
Цитата Сообщение от Lavroff Посмотреть сообщение
maxibon, IDE Visual Studio 2005.
это не компилятор а среда разработки// ладно, попробую зпускать show без цикла, а сразу после присваивания ему объекта. Всеи кто ответил спасибо1
0
ForEveR
27.07.2010, 16:16
  #9

Не по теме:

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

0
CheshireCat
Эксперт С++
2895 / 1244 / 78
Регистрация: 27.05.2008
Сообщений: 3,398
27.07.2010, 16:19 #10
Цитата Сообщение от maxibon Посмотреть сообщение
Но почему тогда выводится 3 3 3, а не еще что-нибудь...
А может выводить хоть "Hello, World!", если заблагорассудится. Временных объектов уже не существует, а обращение (по указателю) к несуществующему объекту - это UB. Как именно это UB проявится - это Б.Г. его знает....
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
27.07.2010, 16:29 #11
Цитата Сообщение от maxibon Посмотреть сообщение
ладно, попробую зпускать show без цикла, а сразу после присваивания ему объекта. Всеи кто ответил спасибо1
Это ничего не изменит, т.к. ты инициализируешь указатели временными объектами, которые уничтожаются сразу после инициализации.
0
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;
    }
у некоторых работает?
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
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;
    }
В общем, дело твое, делай как хочешь, но мы тебя предупредили...
1
Evg
Эксперт CАвтор FAQ
18261 / 6386 / 440
Регистрация: 30.03.2009
Сообщений: 17,671
Записей в блоге: 28
27.07.2010, 21:26 #14
А поясните, пожалуйста, что означает конструкция

C++
1
p[0] = &x1();
конструктор вроде бы как нельзя вызывать напрямую
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
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;
}
1
28.07.2010, 06:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.07.2010, 06:45
Привет! Вот еще темы с ответами:

Виртуальные функции - C++
Составить программу в С Buildere. Объявить базовый класс с именем person {имя, возраст, группа}. Определить функцию show (), которая...

Виртуальные функции - C++
Доброго времени суток. Есть задание. Создать абстрактный класс Function (функция) с виртуальными методами вычисления значения функции...

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

виртуальные функции - C++
интересует 2 вопроса:1)Какими элементами могут отличаться экземпляры одной виртуальной функции, находящиеся в разных производных...


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

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

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