MyCoolClass* func1()
{
MyCoolClass *obj = new MyCoolClass;
return obj;
}
MyCoolClass& func2()
{
MyCoolClass val;
return val; // Убивать за такое надо
}
main()
{
func1()->SomeFunc(); // Если возвращается не нулевой объект, то работает
MyCoolClass *obj = func1(); // То же самое..
obj->SomeFunc();
func2().SomeFunc(); // Работает!
MyCoolClass &refObj = func2();
refObj.SomeFunc(); // ОЙ! А что случилось? Access violation
}
Здравствуйте, Аноним, Вы писали:
А>В чем разница между reference & и pointer *? А>Или же они заменяют друг друга...
1. pointer allows NULL, referense not;
2. referense инициализируется один раз, pointer скока хочешь
Это вроде основное,
Здравствуйте, Аноним, Вы писали:
А>В чем разница между reference & и pointer *? А>Или же они заменяют друг друга...
Ссылка может только инициализироваться, инициализация обязательна, присваивание ссылок запрещено.
Ссылка, привязанная к временному объекту управляет его временем жизни.
Передача по ссылке всегда гарантирует наличие объекта, по указателю можно получить NULL.
думаю что человеку от этого вопроса стало не легче... если он задает подобные вопросы — то он только начал разбираться в С++ и грузить его по большей части бессмысленно!
Указатель(*) — просто указывает на какую-то ячейку памяти, память может быть выделена, может нет, но куда-то он в любом случае "смотрит". Вообще указатели — ЭТО ЗЛО!!!! это обычный ИНТ — 4 байтика, над которыми можно известными способами издеваться. Шаг в лево-вправо — приплыли! Причем ошибка с указателями приводят к долгому дебугу, уничтожающему огромное кол-во нервных клеток! С указателями надо быть осторожнее и писать все Красиво!!! А вот как это делать-почитай книжки Cтрауструпа, ну еще кого найдешь...
по ссылке(&) передается сам объект... а предыдущий пост — очень полезен для тебя будет. Удачи в дебуге!!!
Здравствуйте, Аноним, Вы писали: А>Указатель(*) — просто указывает на какую-то ячейку памяти, память может быть выделена, может нет, но куда-то он в любом случае "смотрит". Вообще указатели — ЭТО ЗЛО!!!!
С указатели нужно быть аккуратно, но это мощьнейшая вещь.
Если указатели зло, то весь С++ зло(нет сборщика мусора и т.п.)
Здравствуйте, <Аноним>, Вы писали:
А>Указатель(*) — просто указывает на какую-то ячейку памяти, память может быть выделена, может нет, но куда-то он в любом случае "смотрит". Вообще указатели — ЭТО ЗЛО!!!! это обычный ИНТ — 4 байтика, над которыми можно известными способами издеваться. Шаг в лево-вправо — приплыли! Причем ошибка с указателями приводят к долгому дебугу, уничтожающему огромное кол-во нервных клеток! С указателями надо быть осторожнее и писать все Красиво!!!
Забавно. Всегда считал, что указатели развязывают руки. Это как нож. Им можно порезать хлеб, вырезать игрушку.. Но если драйвер "руки прямые, две штуки" не установлен, то ножем можно отрезать себе и последние.
Пример приведу, как ты без указателей реализуешь L2 список например? Естественно, с возможностью удаления и добавления в середину? Это, между прочим, задача почти ежедневная (естественно, не в таком виде, но очень похожем).
Еще пример. В С++ нет встроенного типа Массив. Есть указатель на память с возможностью "известными способами издеваться".
А взять хотя бы механизм виртуальных функций? Он же вообще без указателей теряет смысл!
А для начинающего, имхо, вообще жизненно необходимо знать и использовать указатели. Это во-первых направляет мозг в правильном русле, во-вторых тренирует память (выделил -- освободи! )
L>>во-вторых тренирует память (выделил -- освободи! ) LM>В целом прав. Но не проще ли дать освобождение самому компилеру( using smart pointer)
ИМХО для начинающего -- smart pointer как раз вред. Ведь если есть два объекта, у которых внутри указатели (умные) друг на друга, то в этом случае память так и не освободится... Так что думаю, сначала надо научиться работать с памятью руками, а потом использовать автоматизацию.
тема указателей двоякая: с одной стороны — это мощное средство, с другой — куча возможного гемороя! Особенно раздражжает, когда кто-то ошибся, похерил памать, а падать начинает в месте, где ты ответственный! Все пистоны насобираешь, кучу времени потратишь, ради глупой улыбки коллеги и застенчивого "сорри"...
Здравствуйте, Hades, Вы писали:
H>тема указателей двоякая: с одной стороны — это мощное средство, с другой — куча возможного гемороя! Особенно раздражжает, когда кто-то ошибся, похерил памать, а падать начинает в месте, где ты ответственный! Все пистоны насобираешь, кучу времени потратишь, ради глупой улыбки коллеги и застенчивого "сорри"...
Страшная история.. Просто жуткая... Но чтобы добраться до такого надо сначала выучить зачем это нужно.
Ну а уж потом... Как в анекдоте, "вырастит, само решит" Когда умеешь пользоваться много чем вот тогда и появляется свобода выбора решений.
Здравствуйте, Leshi, Вы писали:
L>Здравствуйте, LuciferMoscow, Вы писали:
L>>>во-вторых тренирует память (выделил -- освободи! ) LM>>В целом прав. Но не проще ли дать освобождение самому компилеру( using smart pointer) L>ИМХО для начинающего -- smart pointer как раз вред. Ведь если есть два объекта, у которых внутри указатели (умные) друг на друга, то в этом случае память так и не освободится... Так что думаю, сначала надо научиться работать с памятью руками, а потом использовать автоматизацию.
Здравствуйте, Alik, Вы писали:
A>Ссылка может только инициализироваться, инициализация обязательна, присваивание ссылок запрещено.
угу
A>Ссылка, привязанная к временному объекту управляет его временем жизни.
вообще — нет.
или вы про какой-то случай?
A>Передача по ссылке всегда гарантирует наличие объекта, по указателю можно получить NULL.
не гарантирует.
struct A
{
int k;
public:
A() : k(10) {std::cout<<"A::A()\n";}
~A() {std::cout<<"A::~A()\n";}
};
void Foo(const A& p_a)
{
std::cout << p_a.k;
}
int main()
{
A* a = new A();
A& a_ = *a;
delete a;
Foo(a_);
return 0;
}
Здравствуйте, Ovl, Вы писали:
A>>Ссылка может только инициализироваться, инициализация обязательна, присваивание ссылок запрещено. Ovl>угу
A>>Ссылка, привязанная к временному объекту управляет его временем жизни. Ovl>вообще — нет. Ovl>или вы про какой-то случай?
Про
{
Base& ref = make_derived(); // результат выражения make_derived() - временный объект типа Derived
...
access_to_base(ref);
...
}// вот здесь заканчивается время жизни того анонимного объекта, доступного через ref
A>>Передача по ссылке всегда гарантирует наличие объекта, по указателю можно получить NULL. Ovl>не гарантирует.
Любые манипуляции с инвалидными указателями, ссылками, итераторами и дескрипторами — это неопределённое поведение. Сам себе злой буратино. Хочешь — расстреляй кучу и после этого скажи, что malloc() не гарантирует валидный указатель.
Здравствуйте, LuciferMoscow, Вы писали:
L>>>>во-вторых тренирует память (выделил -- освободи! )
LM>>>В целом прав. Но не проще ли дать освобождение самому компилеру( using smart pointer)
L>>ИМХО для начинающего -- smart pointer как раз вред. Ведь если есть два объекта, у которых внутри указатели (умные) друг на друга, то в этом случае память так и не освободится... Так что думаю, сначала надо научиться работать с памятью руками, а потом использовать автоматизацию.
LM>Сейчас имел ввиду std::auto_ptr
Как по мне, std::auto_ptr можно начинать использовать, когда можешь сам его написать.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, LuciferMoscow, Вы писали:
L>>>>>во-вторых тренирует память (выделил -- освободи! )
LM>>>>В целом прав. Но не проще ли дать освобождение самому компилеру( using smart pointer)
L>>>ИМХО для начинающего -- smart pointer как раз вред. Ведь если есть два объекта, у которых внутри указатели (умные) друг на друга, то в этом случае память так и не освободится... Так что думаю, сначала надо научиться работать с памятью руками, а потом использовать автоматизацию.
LM>>Сейчас имел ввиду std::auto_ptr
C>Как по мне, std::auto_ptr можно начинать использовать, когда можешь сам его написать.
И когда сам поймешь, когда именно его нужно писать.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Willi, Вы писали:
L>>А взять хотя бы механизм виртуальных функций? Он же вообще без указателей теряет смысл! W>Вот пример, демонстрируюший работу механизма виртуальных функций без использования указателей:
Я не говорил, что виртуальные функции невозможны без указателей. Я говорил, что смысл теряется. Ссылка должна быть инициализирована при создании и это ее главный минус (в контексте работы с виртуальными функциями). Можно, конечно, изварачиваться через функции вида A& getThis(){return *this;}, но тут опять работа со ссылками... (this то же указатель)
На сколько я понимаю прелести виртуальных функций, они в первую очередь служать для того, чтобы иметь массивы указателей на однотипные объекты, хотя на самом деле объекты разные, но выведенные из одного базового класса (сам не понял че сказал ). А массив ссылок.. Это как-то грусно звучит.
Здравствуйте, Leshi, Вы писали:
L>>>А взять хотя бы механизм виртуальных функций? Он же вообще без указателей теряет смысл! W>>Вот пример, демонстрируюший работу механизма виртуальных функций без использования указателей: L>Я не говорил, что виртуальные функции невозможны без указателей. Я говорил, что смысл теряется. Ссылка должна быть инициализирована при создании и это ее главный минус (в контексте работы с виртуальными функциями). Можно, конечно, изварачиваться через функции вида A& getThis(){return *this;}, но тут опять работа со ссылками... (this то же указатель)
L>На сколько я понимаю прелести виртуальных функций, они в первую очередь служать для того, чтобы иметь массивы указателей на однотипные объекты, хотя на самом деле объекты разные, но выведенные из одного базового класса (сам не понял че сказал ). А массив ссылок.. Это как-то грусно звучит.
Не в первую очередь. Далеко не в первую.
Например, передача полиморфного объекта как параметра функции:
Здравствуйте, Кодт, Вы писали:
К>Не в первую очередь. Далеко не в первую.
Спорить не буду. Просто я использую виртуальные функции чаще всего именно так. А приминительно к исколючениям, я вообще не использую виртуальные функции. Ловлю (стараюсь ловить) каждое исключение своим обработчиком, так, мне кажется, более информативно получается. А вообще, я просто высказывал свое мнение, основанное на собственном опыте
Здравствуйте, Leshi, Вы писали:
L>Здравствуйте, Willi, Вы писали:
L>>>А взять хотя бы механизм виртуальных функций? Он же вообще без указателей теряет смысл! W>>Вот пример, демонстрируюший работу механизма виртуальных функций без использования указателей: L>Я не говорил, что виртуальные функции невозможны без указателей. Я говорил, что смысл теряется. Ссылка должна быть инициализирована при создании и это ее главный минус (в контексте работы с виртуальными функциями). Можно, конечно, изварачиваться через функции вида A& getThis(){return *this;}, но тут опять работа со ссылками... (this то же указатель)
L>На сколько я понимаю прелести виртуальных функций, они в первую очередь служать для того, чтобы иметь массивы указателей на однотипные объекты, хотя на самом деле объекты разные, но выведенные из одного базового класса (сам не понял че сказал ). А массив ссылок.. Это как-то грусно звучит.
Ну почему именно массивы. Основное предназначение виртуальных функций — переопределение поведения базового класса.
Я же хотел подчеркнуть, что можно прекрасно использвать этот механизм, не используя указателей.
Например есть некая функция, которая принимает ссылку на базовый класс и вызывает у него виртуальные функции. Можно передать в нее наследника и все будет работать без всяких указателей и без потери смысла.
class Base
{
...
virtual void f() {}
};
class Derived : public Base
{
...
virtual void f() {}
};
void UsefulFunc(Base& base)
{
...
base.f();
...
}
...
Derived d;
UsefulFunc(d);
...
и никаких указателей.
Я не против указтелей. Я за точность формулировок.
К>{
К> Base& ref = make_derived(); // результат выражения make_derived() - временный объект типа Derived
К> ...
К> access_to_base(ref);
К> ...
К>}// вот здесь заканчивается время жизни того анонимного объекта, доступного через ref
К>
Что самое неприятное — привязка к rvalue работает только при такой записи.
Нет никакого способа инициализировать константную ссылку-член класса rvalue извне так, чтобы соответствующим образом продлилось время жизни — ссылка-то проинициализируется молча, а временный объект тут же и умрет и мы словим access violation или еще чего хуже.
Здравствуйте, <Аноним>, Вы писали:
А>В чем разница между reference & и pointer *? А>Или же они заменяют друг друга...
Ссылка (reference) является альтернативным именем объекта.
Объявление переменной в качестве ссылки на другую переменную определяет ее алиас.
int i = 1;
int& iref = i; // i и iref ссылаются на одно и то же целое
Операций над ссылками не существует. Хотя выражение iref++ (эквивалентное
iref = iref + 1) допустимо, но оно не увеличивает ссылку iref, оператор ++ применяется только к целому значению i.
Как следствие, значение ссылки нельзя изменить после инициализации. Она всегда ссылается на объект, которым инициализирована.
Чтобы получить указатель на объект, именем которого является ссылка iref, мы можем написать
int* p = &iref;
Реализацией ссылки является (константный) указатель, при каждом использовании которого
происходит разыменование. Например, последовательность инструкций:
int i = 1; int& iref = i; iref++; int* p = &iref;
можно смоделировать следующим образом:
int i = 1; int* const iref = &i; (*iref)++; int* p = &(*iref);
При этом надо понимать, что ссылка, в отличие от указателя, не является объектом, над которым можно выполнять операции.