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

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

Войти
Регистрация
Восстановить пароль
 
 
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
#1

Интересная инициализация ссылки - C++

06.07.2013, 22:06. Просмотров 686. Ответов 19
Метки нет (Все метки)

Доброго времени суток.
Рассмотрим вот такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Base
{
public:
    Base(Base *instance, 
         unsigned int NumElems):
      vec(NumElems),
      vec_ref(instance->vec)
    {}
    std::vector<float> vec;
    std::vector<float>& vec_ref;
};
 
class Der : public Base
{
public:
    Der() : Base(nullptr, 5){}
};
Эта штука вполне удачно компилируется, однако, смущает то, как инициализируется ссылка vec_ref в конструкторе - ссылка ведь не может быть NULL как указатель. Получается, что в конструкторе Base происходит нечто вроде nullptr->vec. Так что же в данном случае представляет собой vec_ref после инициализации и насколько безопасен такой код?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2013, 22:06     Интересная инициализация ссылки
Посмотрите здесь:

интересная головоломка - C++
помоготе решить задачу про спички я уже неделю голову ломаю....Даны n-спичек и 2 игрока,каждый может вытянуть от 1 до 3 спичек...выигрывает...

Интересная конструкция в C++ - C++
Добрый день. Подскажите пожалуйста, что это такое: float time = clock.getElapsedTime().asMicroseconds();

Интересная сортировка - C++
Добрый день . Увидел задачу не могу решить :cry::-| какой час уже . Вообщем есть массив : Вот 3 2 7 5 6 7 После того как 7 (то есть х )...

Интересная задачка - C++
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; int main() { double z1,z2; double a,b,c,d,s,t,u; ...

Интересная сортировка - C++
Помогите пожалуйста с задачкой,если можно с комментариями Ввести матрицу и провести сортировку всех столбцов следующим...

Интересная головоломка - C++
1.С помощью текстового редактора создать файл который содержит текст.Длина ряда с текстом не должна превышать 80 символов.Это входной файл....

Интересная штука - C++
Интересная штука происходит. Создал я значит сетевое приложение, ну естественно подключена ws2_32.lib. Так вот, даже закомпилированная в...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
06.07.2013, 22:09     Интересная инициализация ссылки #2
это код с неопределенным поведением и скорее всего крашем.
синтаксически все верно. но в рантайме начнутся проблемы, т.к. тут попытка обратится к члену какого-то объекта через нулевой указатель.
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
06.07.2013, 22:11  [ТС]     Интересная инициализация ссылки #3
DU, lда, это я уже проверил - дамп памяти получился. но если не обращаться к этому элементу, то все вроде бы ок. я вот хотел бы уточнить, не чревато ли это утечками какими-нибудь, если код оставить как есть, но не обращаться к элементу vec_ref, инициализированному как показано выше?
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
06.07.2013, 22:12     Интересная инициализация ссылки #4
Цитата Сообщение от Gorillych Посмотреть сообщение
ссылка ведь не может быть NULL как указатель
Нет, так и в коде этого тоже нет.
Цитата Сообщение от Gorillych Посмотреть сообщение
Получается, что в конструкторе Base происходит нечто вроде nullptr->vec.
Ну да, ссылка на вектор инициализируется вектором. Что не так?
Цитата Сообщение от Gorillych Посмотреть сообщение
насколько безопасен такой код?
Не на сколько, он же в рантайме сломается
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
06.07.2013, 22:14  [ТС]     Интересная инициализация ссылки #5
Цитата Сообщение от Kastaneda Посмотреть сообщение
Не на сколько, он же в рантайме сломается
сломается, только если к этой ссылке обратиться
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
06.07.2013, 22:17     Интересная инициализация ссылки #6
Цитата Сообщение от Gorillych Посмотреть сообщение
сломается, только если к этой ссылке обратиться
а nullptr->vec не смущает?
Croessmah
Модератор
Эксперт CЭксперт С++
13057 / 7320 / 817
Регистрация: 27.09.2012
Сообщений: 18,066
Записей в блоге: 3
Завершенные тесты: 1
06.07.2013, 22:17     Интересная инициализация ссылки #7
Gorillych, Ссылка безопаснее лишь тем, что не может быть не инициализированной, но никто не запрещает инмциализировать ее не верными данными
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
06.07.2013, 22:19     Интересная инициализация ссылки #8
ну есть негласное правило, когда лучше ссылки использовать, а когда указатели.
если ваш класс может корректно работать в случае, когда ему передадут нулевой указатель (типа специально предусмотрена такая возможность для какого-нибудь там дефолтного поведения) - то передаем в него указатель.
если не может (в вашем случае - не может. т.к. внутренний член инициализируется членом, получаемым от переданного в конструктор объекта), то тут лучше воспользоваться ссылкой, т.к. ссылки вроде как как всегда ссылаются на какой-то объект. "вроде как" - это не всегда так, но в этом случае ответственность на вызывающей стороне. она должна следить, чтобы в конструктор приходила ссылка на существующий объект. т.о., использование ссылки вместо указателя намекает вызывающей стороне что сюда нужно отдавать что-то существующее, иначе сам дурак.
Gorillych
14 / 14 / 1
Регистрация: 04.07.2013
Сообщений: 76
06.07.2013, 22:34  [ТС]     Интересная инициализация ссылки #9
Croessmah, жаль, лучше бы уж компилятор ругался в таких случаях

Добавлено через 11 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
а nullptr->vec не смущает?
смущает, конечно) поэтому и тему создал

Добавлено через 3 минуты
DU, если vec_ref будет не ссылкой, а указателем, от этого что-то принципиально изменится в рантайме?
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
06.07.2013, 22:38     Интересная инициализация ссылки #10
Цитата Сообщение от Gorillych Посмотреть сообщение
смущает, конечно) поэтому и тему создал
Так оно сломается в момент обращения по nullptr, т.е. еще до инициализации ссылки.

Добавлено через 45 секунд
Цитата Сообщение от Gorillych Посмотреть сообщение
если vec_ref будет не ссылкой, а указателем, от этого что-то принципиально изменится в рантайме?
нет, просто в этом случае оно упадет в момент инициализации указателя, а не в момент инициализации ссылки
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
06.07.2013, 22:44     Интересная инициализация ссылки #11
нет. не будет. ссылки и указатели транслируются компилятором в один и тот же бинарный код.

на счет сломается - не факт. поскольку Obj* obj = &superOjbPtr->obj - это не изменяющее обращение.
т.к. компилятор знает, смещение в памяти объекта obj относительно объекта superObj и в данном случае мы получаем указатель на obj, то компилятор может просто сгенерировать код obj = superObjPtr + смещение = 0 + смещение. т.е. тут арифметика указателей вполне может оказаться так, что ничего не случится. а вот при попытке изменить obj за счет вызова какого-нибудь метода или просто изменить, если это какой-нибудь инт, вот тут будут проблемы, т.к. obj указывает хз куда.
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
06.07.2013, 22:52     Интересная инициализация ссылки #12
Цитата Сообщение от DU Посмотреть сообщение
компилятор может просто сгенерировать код obj = superObjPtr + смещение = 0 + смещение.
Ну да, так оно и будет, только адрес получится очень маленьким (если только смещение не равно паре гигов ), а в современных десктопных ОСях это тоже недопустимо. Может под какое-нибудь специфичное устройство со специфичной ОСью это и будет работать (всмысле не скрэшится), но винда и линукс на х86 выкинут исключение.

P.S. хотя замечание в целом верное, я что-то неподумав написал.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
06.07.2013, 22:55     Интересная инициализация ссылки #13
вот тестик в 2012 студии. инициализация через нулевой указатель не крашится. крашится попытка изменения.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
struct Struct
{
  int structMember;
};
 
struct SuperStruct
{
  char offset[8];
  Struct str;
};
 
int main()
{
  SuperStruct* superStruct = nullptr;
  Struct* structPtr = &superStruct->str;
  Struct& structRef = superStruct->str;
  std::cout << "address of struct = 0x" << structPtr << std::endl;
  std::cout << "address of struct = 0x" << &structRef << std::endl;
//  structRef.structMember = 5; // runtime error.
  return 0;
}
output:
address of struct = 0x00000008
address of struct = 0x00000008
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,249
Записей в блоге: 1
Завершенные тесты: 1
06.07.2013, 22:56     Интересная инициализация ссылки #14
Цитата Сообщение от DU Посмотреть сообщение
а вот при попытке изменить obj за счет вызова какого-нибудь метода или просто изменить. если это какой-нибудь инт, вот тут будут проблемы, т.к. obj указывает хз куда.
Да, верно. Вот это
Цитата Сообщение от Kastaneda Посмотреть сообщение
но винда и линукс на х86 выкинут исключение.
я писал опять не думая У меня в голове картина по другому выглядела (там почему-то было obj = *(0 + offset))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2013, 23:00     Интересная инициализация ссылки
Еще ссылки по теме:

Интересная сортировка - C++
Дан вектор.Сжать существующий вектор,удалив все отрицательные элементы,не используя дополнительный вектор. Огромная,просьба...

Интересная штука на размышляловку:) - C++
В каждой из 9 клеток квадрата 3 х 3 пороставлять числа 1,2,3 так, чтоб суммы чисел в каждой горизонтальной строке, в каждой вертикальной...

Интересная програмка попалась - C++
Доброго времени суток!!! У меня такая проблемка нужно решить задачку но ничего в голову не лезет. В массиве имеются измерений температуры...

Очень интересная задачка на C++ - C++
Исследовать сходимость ряда Фурье по косинусам для функции f(x)=l-x на отрезке ,l=1. Определить, сколько членов ряда Фурье необходимо...

очень интересная задание - C++
Паша очень любит готовить сэндвичи. Свой фирменный сэндвич «Купе» он готовит из четырех главных ингредиентов: верхний кусок хлеба, ломтик...


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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
06.07.2013, 23:00     Интересная инициализация ссылки #15
Цитата Сообщение от Gorillych Посмотреть сообщение
ссылка ведь не может быть NULL как указатель.
Может. Но стать NULL она не может, а только быть изначально. И поменяться может только NULL ссылка.
Yandex
Объявления
06.07.2013, 23:00     Интересная инициализация ссылки
Ответ Создать тему
Опции темы

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