Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   указатели (http://forum.oszone.net/showthread.php?t=58215)

papam 17-12-2005 22:11 384213

указатели
 
Помогите пожалуста:
  1. Написать функцию my_swap с использованием ссылочных параметров. Необходимо изменить механизм передачи аргументов в функцию (в примере передача аргументов в функцию происходила с помощью указателей. Ваша задача - изменить передачу аргументов в функцию использовав механизм ссылок, а не указателей)

SergeCpp 19-12-2005 08:30 384539

Swap( int& a, int& b )
{
int c( a );

a = b;
b = c;
}

Zippy 19-12-2005 21:46 384827

ого, первый раз вижу такую конструкцию: int c( a );, проверил, даже работает! ох уж этот си, хотя на мой взгляд нагляднее просто int с = a;

pva 22-12-2005 08:50 385704

В C++ эта конструкция правильней. Она обозначает явный вызов конструктора копирования.
Ещё полезные примеры:
Код:

double x = double(); // то же самое, что double x(double()), но с явным вызовом.

class X
{
public: explicit X() {cout << "X::X()\n";}
}

X x = X(); // сработает
X x(X()); // сработает
X x; // ошибка - нет неявного конструктора.
X x(); // ошибка - описание функции;

template<class T> class temp1
{
    double y;
    X x;
public: temp1() : x(), y() {} // вызов явных конструкторов, x=X(), y=double()
}


SergeCpp 22-12-2005 11:49 385765

Если есть интерес, то вот обсуждение одного из способов употребления этой конструкции на RSDN...

Кстати, я даже писал Bjarne Stroustrup по этому поводу...

И он мне ответил...

Prof. Bjarne Stroustrup


Собственно, могу порекомендовать свои программы...

SergeCpp 22-12-2005 12:01 385774

pva, небольшая неаккуратность... (не ошибка!)

Код:

template<class T> class temp1
{
double y;
X x;
public: temp1() : x(), y() {} // вызов явных конструкторов, x=X(), y=double()
}

Действительный порядок вызова конструкторов для членов — тот, который в объявлении класса...

То есть, сначала — y(), а потом — x()...

Можно, конечно, писать x(), y(), ничего от этого не изменится...

Но, например, новички (да и просто по рассеянности) могут подумать,
что Вы специально так написали, чтобы изменить порядок создания членов...

Лично я стараюсь всегда указывать в порядке объявления...

pva 22-12-2005 13:00 385814

Почитал предложенные ссылки, проверил на доступных сейчас компиляторах
Код:

if (int ok(123))
{
}

Один считает это синтаксической ошибкой, другой уточняет, что ему не нравится инициализация переменной в условии.
Если цель стояла в создании класса и приведении его к bool, можно было сделать: if (SomeClass(123)) ...
[code]
class A
{
public:
explicit A(int) {}
operator bool() const {return false;}
};

int main()
{
for(A a (123); A b(123)/*ошибка*/; ) {}

if (A a(123)/*ошибка*/)
{
///
}

return 0;
}
[code]
Короче, я понял, что дело в объявлении переменных:
Код:

bool(A a(123))
- ошибка

По поводу "пыльных углов":
попродуйте код:
Код:

std::vector<A*> as;
// fill some way with operator new

std::for_each(as.begin(), as.end(), delete);

Ничего не уничтожится.

pva 26-12-2005 11:32 386833

Если ещё интересно про A a(123) и for_each(delete):

В С/C++ все выражения принимаются в виде lvalue = rvalue (левому присвоить правое). lvalue должна иметь адрес в памяти, rvalue - значение. Формально A a = A(123) значит {A a; a=A(123)}, то есть по синтаксису используется A& operator=(...), который возвращает rvalue. Конструкции, где используется значение, например if (...), требуют rvalue, а конструкция объявления переменных A a(123) не является rvalue (это lvalue). Подобно этому, {A b(124), a=A(123)} - тоже не может быть приведена к rvalue. Между тем, компиляторам рекомендуется делать оптимизацию, уменьшающую количество копирований, даже если имеются побочные эффекты присваивания, копирования и разрушения объектов. На синтаксисе это не сказалось.

Я проверил, что делает for_each(begin, end, operator delete) на предмет повреждения памяти. Оказалось, что здесь шаблон for_each(Iterator, Iterator, Transform) раскрывается как for_each(vector<A*>::iterator, vector<A*>::iterator, operator delete(void*)), То есть освобождение памяти есть, а вызова деструктора - нет (даже если он виртуальный).

Тесты проводились в том числе на GCC 3.3.2.


Время: 02:38.

Время: 02:38.
© OSzone.net 2001-