crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Указатель на ссылку?
Litkevich Yuriy
  опции профиля:
сообщение 12.2.2010, 0:51
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Наткнулся на такую запись:
static void createDA(XSQLDA *&sqlda)
{
...
}
sqlda - это что указатель на ссылку?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 12.2.2010, 8:30
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Litkevich Yuriy @ 12.2.2010, 0:51) *
Наткнулся на такую запись:
static void createDA(XSQLDA *&sqlda)
{
...
}
sqlda - это что указатель на ссылку?

Наоборот. Указателей на ссылку быть не может.

Эквивалентна следующей записи:
static void createDA(XSQLDA **sqlda)
{
    *sqlda = new XSQLDA;
}

void func()
{
    XSQLDA *data;
    createDA( &data );
    createDA( 0 );        // Да пожалуйста
}

Только в эту функцию можно передать 0, если же использовать ссылку, то параметр должен быть указателем на объект:

static void createDA(XSQLDA *&sqlda)
{
    sqlda = new XSQLDA;
}

void func()
{
    XSQLDA *data;
    createDA( data );
    createDA( 0 );        // ОШИБКА!
}


Сообщение отредактировал BRE - 12.2.2010, 9:14
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.2.2010, 18:42
Сообщение #3


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


я думаю, что это простой аналог выражения **.
выражение TypeX *&X означает, что &X является выражением типа TypeX*, то есть, указателем на тип TypeX. а ссылка - просто переименование объекта X. таким образом, операнд X является указателем на TypeX.

новый объект сам по себе не создаётся, ноль там или не ноль - безразлично. функция внутри должна проверять значение операнда и может его менять по своему усмотрению.

вот пример тестового кода - ради интереса:
#include <iostream>

class bar
{
    private:
        int blablabla;
};

void foo(bar *&x)
{
    std::cout << "x=" << std::hex << x << std::endl;
}

int main()
{
    bar* px;
    std::cout << "px=" << std::hex << px << std::endl;
    foo(px);
    return 0;
}


пример вывода программы:
px=0x8048969
x=0x8048969


указатели px и x эквивалентны. ничего не создаётся. если будет ноль - он останется нулём. но, понятное дело, есть возможность изменить его значение внутри функции и тогда элемент по ссылке px уже будет содержать другое значение.

Сообщение отредактировал Iron Bug - 12.2.2010, 18:44
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 12.2.2010, 18:55
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Iron Bug @ 12.2.2010, 18:42) *
я думаю, что это простой аналог выражения **.

Вроде я это и написал. Только ссылка на указатель является безопасной, потому что по ней нельзя передать что угодно, а только указатель на конкретный тип.

Цитата(Iron Bug @ 12.2.2010, 18:42) *
новый объект сам по себе не создаётся, ноль там или не ноль - безразлично. функция внутри должна проверять значение операнда и может его менять по своему усмотрению.

Я нигде не писал про создания новых объектов.
Попробуй скомпилировать свой пример:
#include <iostream>

class bar
{
    private:
        int blablabla;
};

void foo(bar *&x)
{
    std::cout << "x=" << std::hex << x << std::endl;
}

int main()
{
    bar* px;
    std::cout << "px=" << std::hex << px << std::endl;
    foo(px);    // все нормально
    foo( 0 );    // компилятор выдаст ошибку (хотя если бы была декларация bar **x - этого бы не произошло.)
    return 0;
}


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.2.2010, 19:45
Сообщение #5


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


значит, просто я твоё изложение не поняла.
однако, вся эта шелуха имеет смысл лишь на этапе компиляции. оптимизации она не несёт никакой - ведь передаваться будет всё равно значение указателя, а это просто "защита от дурака", так сказать: ведь наверняка перед применением функции надо посмотреть документацию или сорц :) хотя, может быть, кому-то и такая защита полезна. а то сейчас мне многие говорят, что Си "небезопасен". имхо, это такие программисты небезопасны, а не Си :)

Сообщение отредактировал Iron Bug - 12.2.2010, 19:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 12.2.2010, 19:59
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Iron Bug @ 12.2.2010, 19:45) *
значит, просто я твоё изложение не поняла.
однако, вся эта шелуха имеет смысл лишь на этапе компиляции. оптимизации она не несёт никакой - ведь передаваться будет всё равно значение указателя, а это просто "защита от дурака",

Ну ссылки и были придуманы для обеспечения дополнительной безопасности, что бы ошибки можно было ловить на этапе компиляции, а не исполнения.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.2.2010, 20:12
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Собственно код функции вот:
static void createDA(XSQLDA *&sqlda)
{
    sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
    if (sqlda == (XSQLDA*)0) return;
    sqlda->sqln = 1;
    sqlda->sqld = 0;
    sqlda->version = SQLDA_CURRENT_VERSION;
    sqlda->sqlvar[0].sqlind = 0;
    sqlda->sqlvar[0].sqldata = 0;
}
это файл %QTDIR%/src/sql/drivers/ibase/qsql_ibase.cpp
(Qt 4.6.0)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 28.9.2010, 20:09
Сообщение #8





Гости








    


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

sqlda это ссылка на указатель, этот участок кода означает что значение указателя, т.е адресс на который он указывает может быть изменено т.к не указанн модификатор const т.е
void fooPModifer(Foo* & p);

Foo * k=new Foo("1");//k указывает на 1 обьект
fooPModifer(k);
//к теперь указывает на 2 обьект
void fooPModifer(Foo* & p)
{
    p=new Foo("2);// указатель переданный по ссылке изменен
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 28.9.2010, 21:44
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(Litkevich Yuriy @ 12.2.2010, 3:51) *
XSQLDA *&sqlda


мне лично больше нравится, когда символы * и & визуально прилеплены к типу (поскольку они тоже определяют тип) , хотя и это невозможно при записи вида
int* a, b, *c; //а я такую запись терпеть ненавижу и никогда не использую )


а чем нравится ? А тем, что сразу видно назначение: тип слева, идентификатор справа:

//тип идентификатор переменной
XSQLDA*& sqlda;

дальше (хоть и звучит всё банально, зато работает железно): тип "XSQLDA*&" - это ссылка на тип "XSQLDA*", который - указатель на тип "XSQLDA"

    int i;
    int* pi=&i;
    int*& pri=pi;
    int&* rpi=&pri;//если бы это было можно


Сообщение отредактировал Алексей1153 - 28.9.2010, 21:45
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.9.2010, 22:19
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


по-моему уже давно разобрались :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.4.2024, 18:59