Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/163: Рейтинг темы: голосов - 163, средняя оценка - 4.91
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700

Указатель на ссылку или что это такое?

10.03.2017, 11:44. Показов 31494. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
void add(char aData, Branch *&aBranch);
Речь об аргументе aBranch.
Как это понимать? Указатель на ссылку? Не понятно. Вроде такое не имеет смысла
Или это своего рода упрощенное использование указателя на указатель?
Прошу объяснить

Добавлено через 6 минут
На СИшном компиляторе не компилится... Значит плюсовая фича
Но чего оно делает?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.03.2017, 11:44
Ответы с готовыми решениями:

Как получить ссылку на указатель или указатель на указатель в массиве?
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

Нюансы синтаксиса: запись double *array - это указатель или что-то иное?
double *array * что это указатель или что?

Что такое хэндлер файла? Что такое файловый указатель?
Что такое хэндлер файла? Что такое файловый указатель?

34
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
24.12.2018, 01:54
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DrOffset Посмотреть сообщение
Первый аргумент - это std::cout. Запись std::cout << a; - это синтаксический сахар для вот такого вызова operator<<(std::cout, a);.


В случае, если мы говорим о встроенных версиях * и & (т.е. об отсутствии их перегрузок) компилятор не порождает дополнительных инструкций для такой записи. Т.е. да, в вашем случае это эквивалентно.


В обобщенных алгоритмах, например при работе с итераторами, эта запись поможет вытащить настоящий адрес элемента. Там это важно как раз из-за возможной перегрузки operator* и\или operator&.
Спасибо, но если компилятор игнорирует обе операции "&*" и принимает только эквивалент просто "a" потому что не порождает дополнительных инструкций то например почему срабатывает такое "cout << *&*a" ? в итоге выводит уже 1 элемент, а не всю строку, и даже такое "cout << &*&*a"тут явно какую-то компилятор не проигнорил.
А в таком моменте происходит следующее:
C++
1
2
char r[10] = "hello";
char *s = &*r;
здесь указатель s получает адрес только первого элемента разыменованного указателя и все?
здесь уже ничего не игнорируется?
и еще вопрос
в перегруженной функции"cout<<" когда она принимает указатель и выводит всю строку до нуля терминатора, она получает адрес самого указателя, а не первого элемента?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
24.12.2018, 11:21
Цитата Сообщение от Achill Посмотреть сообщение
о если компилятор игнорирует обе операции "&*" и принимает только эквивалент просто "a" потому что не порождает дополнительных инструкций то например почему срабатывает такое "cout << *&*a" ?
Компилятор не игнорирует.
Компилятор видит, что результаты выражений эквивалентны и не генерирует дополнительный бессмысленный код.
Ваше cout << *&*a; эквивалентно cout << *a;.
Предыдущие cout << &*a; эквивалентно cout << a;.
Естественно все это в силе, если мы говорим о встроенных версиях этих операторов. Если они перегружены, то в общем случае каждая операция будет выполнена.

Цитата Сообщение от Achill Посмотреть сообщение
C++
1
2
char r[10] = "hello"; 
char *s = &*r;
Лишних инструкций здесь также не будет. Т.е. это эквивалентно char * s = r;.
Эта ситуация ничем не отличается от варианта с cout. Почему вы решили будто бы здесь что-то будет иначе?

Цитата Сообщение от Achill Посмотреть сообщение
s получает адрес только первого элемента разыменованного указателя и все?
Это очень странная фраза. У указателя нет никаких "элементов".
Элементы есть у массива.
Указатель - это курсор. Он может указывать на один из элементов последовательности заданной массивом или на одиночный объект.
Возьмите листочек в клеточку, нарисуйте там карту для морского боя. Вы когда в морском бое делаете ход, называете координату клетки, например, А-1 - это и есть адрес. Если вы выделите клетку под эту запись A-1, то вы создаете переменную-указатель, которая содержит заданный адрес. Если вы выделили несколько клеток подряд, то получаете массив. Это же очень просто. Порисуйте, разберитесь.

Цитата Сообщение от Achill Посмотреть сообщение
когда она принимает указатель и выводит всю строку до нуля терминатора, она получает адрес самого указателя, а не первого элемента?
Она получает адрес первого элемента (ну или любого другого, какой укажете). Главное, чтобы конец последовательности, в которую входит этот элемент, оканчивался байтом со значением "ноль". Иначе функция не будет иметь возможности остановить цикл.
3
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
24.12.2018, 13:20
Цитата Сообщение от DrOffset Посмотреть сообщение
Компилятор не игнорирует.
Компилятор видит, что результаты выражений эквивалентны и не генерирует дополнительный бессмысленный код.
Ваше cout << *&*a; эквивалентно cout << *a;.
Предыдущие cout << &*a; эквивалентно cout << a;.
Естественно все это в силе, если мы говорим о встроенных версиях этих операторов. Если они перегружены, то в общем случае каждая операция будет выполнена.


Лишних инструкций здесь также не будет. Т.е. это эквивалентно char * s = r;.
Эта ситуация ничем не отличается от варианта с cout. Почему вы решили будто бы здесь что-то будет иначе?


Это очень странная фраза. У указателя нет никаких "элементов".
Элементы есть у массива.
Указатель - это курсор. Он может указывать на один из элементов последовательности заданной массивом или на одиночный объект.
Возьмите листочек в клеточку, нарисуйте там карту для морского боя. Вы когда в морском бое делаете ход, называете координату клетки, например, А-1 - это и есть адрес. Если вы выделите клетку под эту запись A-1, то вы создаете переменную-указатель, которая содержит заданный адрес. Если вы выделили несколько клеток подряд, то получаете массив. Это же очень просто. Порисуйте, разберитесь.


Она получает адрес первого элемента (ну или любого другого, какой укажете). Главное, чтобы конец последовательности, в которую входит этот элемент, оканчивался байтом со значением "ноль". Иначе функция не будет иметь возможности остановить цикл.
Это выражение cout << *&*a; как можно трактовать? справа на лева 1) разыменование, 2) получение адреса разыменованного указателя, и снова разыменование это адреса Т.Е получает доступ по адресу полученному операцией &?
аналогично cout <<*a; а здесь cout << &*a; разыменование и получение адреса элемента на который указывает указатель, Т.Е тоже самое что cout <<a; потому что в этом выражении "а" так же содержит адрес первого элемента(не обязательно на первый элемент) Выглядит так, будто в этих выражениях операция & это обратное действие операции *


Это очень странная фраза. У указателя нет никаких "элементов".
"s получает адрес только первого элемента разыменованного(получение содержимого по адресу на который указывает указатель) указателя и все?"
char *s = &*r;
здесь я имел ввиду "s" получает адрес который получается в ходе 1)разыменование "r" 2)и получение адреса того элемента на который указывает указатель "r". В итоге это по логике тоже самое что просто char *s = r; потому что "r" так же содержит адрес первого элемента(первой ячейки если учитывать состояние указателя по "дефолту")
C++
1
2
char r[10] = "hello"; 
char *s = &*r;
т.к в этом случае он содержит адрес именно начала "0 индекса", и по этому раз это аналогично char *s = r; по этому компилятор не исполняет эти операции.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
24.12.2018, 13:27
Цитата Сообщение от Achill Посмотреть сообщение
Выглядит так, будто в этих выражениях операция & это обратное действие операции *
Так и есть.
1
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
24.12.2018, 13:29
Цитата Сообщение от DrOffset Посмотреть сообщение
Так и есть.
Спасибо большое! Пока буду считать что я что - то в этом понял
0
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
16.01.2019, 15:43
подскажите пожалуйста на что указывает разыменованный *this здесь?
C++
1
++(*this);
на адрес конструктора(или на значение в конструкторе? тогда как ? и на какое?) или на переменную m_digit?
что получится если это заменить
просто
C++
1
++m_digit;
?

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
#include <iostream>
using namespace std;
class Digit
{
 
private:
    int m_digit;
public:
    Digit(int ndigit=0){
     m_digit=ndigit;
                        }
    Digit& operator++();//prefix
    Digit& operator--();   //prefix
        Digit operator++(int);
        Digit operator--(int);
        int get() const { return m_digit;}
};
Digit& Digit::operator++(){
 
   ++m_digit;
   return *this;
}
Digit& Digit::operator--(){
 --m_digit;
 return *this;
 
}
Digit Digit::operator++(int){
Digit cresult(m_digit);
++(*this);
return cresult;
 
 
}
    Digit Digit::operator--(int){
Digit cresult(m_digit);
--(*this);
return cresult;
 
 
}
    int main(){
 
     Digit cDigit(5);
      ++cDigit;
        cDigit++;
         cout<<cDigit.get()<<endl;
         cout<<cDigit.get()<<endl;
 
 
 
 
 
     return 0;
    }
 
 
}
0
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
16.01.2019, 15:50
Цитата Сообщение от Achill Посмотреть сообщение
подскажите пожалуйста на что указывает разыменованный *this здесь?
что будет если разыменовать обычный указатель? получим объект на который указывает указатель.
что будет если разыменовать this указатель? получим объект на который указывает this.

на какой объект указывает this? на самого себя.
тогда что за объект получится после разыменования this? тот самый объект, для которого был применен this
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
16.01.2019, 16:08
Achill, в функции класса (методе) записи

C++
1
2
3
++m_digit;
++(this->m_digit);
++((*this).m_digit);
эквивалентны и означают работу с полем класса m_digit текущего объекта

Добавлено через 2 минуты
А запись
C++
1
++(*this);
эквивалентна

C++
1
operator++();
или что опять же то же самое
C++
1
(*this).operator++();
1
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
16.01.2019, 22:58
Цитата Сообщение от TRam_ Посмотреть сообщение
Achill, в функции класса (методе) записи

C++
1
2
3
++m_digit;
++(this->m_digit);
++((*this).m_digit);
эквивалентны и означают работу с полем класса m_digit текущего объекта

Добавлено через 2 минуты
А запись
C++
1
++(*this);
эквивалентна

C++
1
operator++();
или что опять же то же самое
C++
1
(*this).operator++();
тоесть вот эта запись
C++
1
++(*this);
вызовет вот этот перегруженный префиксный инкремент?
C++
1
2
3
4
5
Digit& Digit::operator++(){
 
   ++m_digit;
   return *this;
}
и еще 2 вопроса
если в префиксном инкременте с помощью перегруженного ++
C++
1
2
3
4
++a;
вызывается operator++(a);
 
тут все понятно переменная "a" находящаяся справа становится аргументом функции перегруженного оператора ++
то при постфиксном
как происходит вызов если вызов operator++ справа от переменной?
C++
1
2
3
4
b++;
 
b operator++(); ?
как это выглядит на самом деле?
следующий вопрос

почему нельзя делать так? где об этом можно по подробнее узнать?
объявление operator+ в классе -наследнике, в котром вызывается operator+ базового класса

ОШИБКА "error: statement cannot resolve address of overloaded function"

operator+(sterling s2){
sterling::operator+;

}


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
class sterfrac:public sterling
{
 
protected:
 
        long pounds;
    int shilling;
    int pens;
    double decPounds = 0.0;
 
droby a,b;
char ch;
 
public:
 
    sterfrac():sterling(0,0,0){}
    sterfrac(sterling st):sterling(st){}
    sterfrac(double d):sterling(d){}
    sterfrac(long p, int sh, int pe):sterling(p,sh,pe){}
 
operator+(sterling s2){
  sterling::operator+;
 
   }
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
16.01.2019, 23:49
Цитата Сообщение от Achill Посмотреть сообщение
как происходит вызов если вызов operator++ справа от переменной?
Вот как раз operator++() это префиксный (т.е. ++a), не суффиксный
https://ru.wikipedia.org/wiki/... _и_C%2B%2B
Чтобы отличить префиксный и суффиксный (постфиксный) операторы друг от друга, у постфиксных операторов добавлен неиспользуемый формальный параметр типа int. Часто этому параметру даже не дают имя.
Соответственно для a++ нужно вызвать
C++
1
2
int i;
operator++(i);
или
C++
1
operator++(0);
так как константа 0 по умолчанию является целочисленной, а единственная перегрузка оператора сама преобразует в int

Добавлено через 5 минут
Цитата Сообщение от Achill Посмотреть сообщение
ут все понятно переменная "a" находящаяся справа становится аргументом функции перегруженного оператора ++
Вот как раз это заблуждение. Порядок тут вообще не причём, смотри выше.

Цитата Сообщение от Achill Посмотреть сообщение
почему нельзя делать так?
потому что оператор должен возвращать либо ссылку на объект, либо собственно объект (в зависимости от своего типа, в таблице по ссылке перечислены все возможные). То есть

C++
1
2
3
sterfrac operator+(sterling s2){
      return sterling::operator+(s2);
}
1
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
17.01.2019, 01:32
Цитата Сообщение от TRam_ Посмотреть сообщение
Вот как раз operator++() это префиксный (т.е. ++a), не суффиксный
https://ru.wikipedia.org/wiki/... _и_C%2B%2B


Соответственно для a++ нужно вызвать
C++
1
2
int i;
operator++(i);
или
C++
1
operator++(0);
Спасибо но я и написал что "a" префиксный, а не постфиксный.

а вот "b" это постфиксный я написал.
там выше вы не много не так поняли где operator(a)
и первый вопрос заключался не в том как описывать постфиксную перегрузку,
попытаюсь объяснить
вопрос в следующем:

вот например по правилам в перегруженном "+" имеет значение то что левый операнд является вызывающим этот перегруженный оператор
и то что левый операнд становится первым аргументом этой перегруженной функции
а второй аргумент берется с права от знака "+".

В перегруженном "[]" например:
C++
1
2
 for(int j=0; j<LIMIT; j++)  //insert elements
      sa2[j] = j*10;
а в действительности вызов будет эквивалентен этому:
C++
1
2
 for(int j=0; j<LIMIT; j++)  //insert elements
      sa2.operator[](j) = j*10;
а вот например:
C++
1
2
3
запись 
std::cout << a; 
- это эквивалентно вот такому вызову operator<<(std::cout, a);
и тут тоже переменная находится справа от перегруженного знака которая становится аргументом перегруженной функции.

а какие правила подобные существуют для "++" ?
И у меня вопрос как будет так же выглядеть вызов перегруженного ПОСТФИКСНОГО "++"

просто я подумал что в префиксном переменная находящаяся справа от этого перегруженного инкремента и становится аргументом функции

а в постфиксном как? как компилятор понимает то что аргументом перегруженного оператора должна быть переменная слева от знака "++" ?
как будет выглядеть в действительности вызов перегруженного оператора"++"
для префиксного что-то типа " b.operator++() " ?
а для постфиксного тоже самое но с int?
а если реализация вне класса с помощью дружественного метода?
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
17.01.2019, 01:48
Цитата Сообщение от Achill Посмотреть сообщение
И у меня вопрос как будет так же выглядеть вызов перегруженного ПОСТФИКСНОГО "++"
C++
1
2
a.operator++();  // префиксный ++a;
a.operator++(0);  // постфиксный a++;
Да, и место ++ тут определяется наличием или отсутствием аргумента типа int у оператора-члена класса, или наличием/отсутствием второго аргумента типа int для оператора, объявленного вне класса.
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
17.01.2019, 09:08
Цитата Сообщение от Achill Посмотреть сообщение
И у меня вопрос как будет так же выглядеть вызов перегруженного ПОСТФИКСНОГО "++"
Перегрузка в качестве свободной функции
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Some { int x; };
 
Some operator++(Some & x, int)
{
    Some n = x;
    ++x.x;
    return n;
}
 
int main()
{
    Some x{};
    x++;
    // или
    operator++(x, int());
}
Перегрузка в качестве функции-члена класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct Some { 
    int x; 
    Some operator++(int)
    {
        Some n = *this;
        ++x;
        return n;        
    }
};
 
int main() 
{
    Some x{};
    x++;
    // или
    x.operator++(int());
}

Вроде бы эти вещи есть в учебниках, нет?
1
0 / 0 / 0
Регистрация: 26.04.2017
Сообщений: 37
17.01.2019, 11:03
Цитата Сообщение от DrOffset Посмотреть сообщение
Перегрузка в качестве свободной функции
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Some { int x; };
 
Some operator++(Some & x, int)
{
    Some n = x;
    ++x.x;
    return n;
}
 
int main()
{
    Some x{};
    x++;
    // или
    operator++(x, int());
}
Перегрузка в качестве функции-члена класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct Some { 
    int x; 
    Some operator++(int)
    {
        Some n = *this;
        ++x;
        return n;        
    }
};
 
int main() 
{
    Some x{};
    x++;
    // или
    x.operator++(int());
}

Вроде бы эти вещи есть в учебниках, нет?
Реализация свободной функцией и функцией - члена класса есть, а о том как будет выглядеть эквивалентный вызов нет, и вопрос я в конце задал на счет того как этот вызов выглядел бы если бы реализация была с помощью дружественного метода, я так понял что вызов будет все такой же
C++
1
2
3
4
5
6
7
int main() 
{
    Some x{};
    x++;
    // или
    x.operator++(int());
}
Вобщем я так понял что положение знака "++"(постфикс, префикс) определяется имеющимся лишним аргументом int, если он имеется то компилятор будет считать что это постфиксный инкремент.
Если писать просто a++ то тут будет иметь значение то что переменная находится слева от инкремента.
Об этом инфа есть но на этом внимание не заостряется, там пишут только то что лишний аргумент int нужен для того чтобы компилятор отличил перегруженную функцию одного и того же оператора(про все операторы в общем), а на счет влияния этого на префикс и постфикс для оператора "++" типа с int это обязательно будет считаться что есть постфиксный перегруженный оператор "++" и обязательно будет вызываться именно он если компилятор обнаружит что переменная стоит слева от знака инкремента иначе как бы компилятор понял какую функцию вызвать при ++a или b++
очевидно что с помощью положения переменной которая находится справа или слева от знака?
если слева то вызывается та которая с int
А если вызывать по типу a.operator++() то тут уже самому надо указывать наличие или отсутствие лишнего аргумента int.
Об этом инфы у меня вроде нет.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
17.01.2019, 11:53
Цитата Сообщение от Achill Посмотреть сообщение
как этот вызов выглядел бы если бы реализация была с помощью дружественного метода
C++
1
operator++(x, int());
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.01.2019, 11:53

Указатель на ссылку: как это использовать ?
Всем доброго времени суток форумчане. Решил для себя разобраться полностью с указателями и ссылками и по ходу чтения инфы столкнулся с...

как такое правильно писать? это ссылка на указатель?
#include &lt;iostream&gt; using namespace std; char *chch2 = &quot;hello&quot;; char*&amp; f() { char *&amp;chch3 = chch2; return...

Что такое указатель на член класса?
Что такое указатель на член класса?

Что такое указатель на абстрактный класс?
В задании сказано - Методы класса должны принимать указатель на абстрактный класс , что это значит и как это реализовывается?

Что такое указатель и с чем его есть
Я уже не знаю что делать, но в книжке очень непонятно написано про указатели. Не могли бы вы объяснить что такое указатели и зачем они. И...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru