Другие языки программирования и технологии

C++: в чем принципиальная разница между использованием членов класса и указателей на них?

В чем вообще разница между объектом и указателем на объект (например, int n и int * n) я понимаю... Но вопрос вот в чем: допустим есть некий класс CFoo. Какие плюсы и минусы имеет объявление CFoo bar и CFoo * bar? Просто иногда в примерах и уроках используют ссылку на объект, притом сама ссылка никуда не передается как параметр и, вроде как, не так и нужна... Так в чем же поинт? Почему не используется просто CFoo bar?Заранее спасибо!p.s. надеюсь, мой вопрос не такой избитый, как ключи к фотошопу и ссылка на скачку каспера )))
Для класса объявление CFoo bar означает, что в это месте создается объект этого класса. Он будет занимать объем памяти необходимый этому объекту, кроме это вызывается конструктор при создании этого объекта, и деструктор при его удалении. Доступ к членам класса через оператор .

void func(BOOL bUseBar)
{
// Здесь объекта нет
if (bUseBar)
{
// Здесь в стэке выделяется память по объект Bar и вызывается конструктор класса
CFoo Bar;
Bar.Show();

// Здесь (при выходе за пределы области видимости Bar) вызывается деструктор класса
}
else
{
// Здесь никаким объектом не пахнет
}
}

CFoo *pBar; // это просто объявление указателя на объект, т. е. адрес этого объекта.
CFoo &rBar = Bar; // это просто объявление ссылки на объект, т. е. тоже адрес этого объекта. Но, в отличии от указателя, ссылка может быть создана только для уже существующего объекта. Просто написать CFoo &rBar; не получиться, компилятор спросит, а чем инициализировать ссылку?

pBar->Show(); // Вызов члена класса
rBar.Show(); // Аналогично

CFoo *pBar; не создает объекта. Чтобы указатель использовать, его нужно инициализировать, т. е. в переменной должен быть адрес объекта, а не незвестно что. Этот адрес может быть получен извне, как параметр функции, например. Или самостоятельно позаботиться о его создании

CFoo *pBar = new CFoo; // оператор new создает объект (выделяет память под объект, и уже не в стеке) , вызывает конструктор, и возвращает указатель на объект
// ...
// А после позаботиться об удалении этого объекта
delete pBar; // вызывается деструктор и выделенная память освобождается
Сергей Самохвалов
Сергей Самохвалов
21 360
Лучший ответ
Несколько моментов:
1. При передаче в функцию. Если передавать объект по значению, то будет происходить его копирование внутри функции, а если по ссылке или по указателю - то копирования не будет.
2. Объект, созданный как CFoo obj; будет иметь область видимости, ограниченную блоком, в котором он создан. Можно его создать так: CFoo* ptr = new CFoo; В этом случае объект будет существовать до тех пор пока его явно не прибьют через delete.
3. Самое главное. Указателю на базовый класс можно присваивать адрес объекта производного класса и дергать по нему виртуальные функции. Именно для этого в основном и используются указатели и ссылки.
class DFoo : public CFoo { };
class DFoo1 : public CFoo{ };
CFoo* ptr = new DFoo;
...
delete ptr;
ptr = new DFoo1;
...
Арман Муханов
Арман Муханов
18 724
int A;
int *B;

A это переменная то есть обект расположеный в адресном пространстве стыка

а B это указатель на обект.... то есть в этом месте стыка расположен только адрес где находятся сами данные... .

указатель можут указывать куда угодно в адресном пространстве процесса... .

размер указателя в 32 битной системе равен 32 битам ну и 64 в 64битной сответствино;

sizeof(B)=4; в 1 байте 8 бит 4*8=32

да кстати для использования указателя для хранения обекта необходимо ещё выдильть память под обект :-))))

допустим так

unsigned char Buffer[0xFF];

так мы видилили 256 байт в стыке

или так

unsigned char *Buffer;

Buffer=LocalAlloc(LPTR,1024*1024);

а так мы выделили 1МБ под буфер

используя api функцию LocalAlloc