LINUX.ORG.RU

с++ поля класса

 


0

2

привет объясните пожалуйста простую вещь


#include <iostream>

class foo{
public:
foo *p;// я создал поле класса , что является указателем типа foo.
создавать то я создаю, но видимо всей сути не понимаю.
на что влияет тип foo ? о чем он будет говорить компилятору?
};
int main(){


return 0;
}
мне даже самому не посебе от мысли, что не понимаю таких вещей. не поленитесь-растолкуйте


В структуре будет отведено 8 байт под поле адреса. Компилятор будет следить за тем, чтобы этот адрес инициализировался не абы чем, а только указателем на объект класса foo.

Crocodoom ★★★★★
()
Последнее исправление: Crocodoom (всего исправлений: 1)

на что влияет тип foo ?

На компилятор.

о чем он будет говорить компилятору?

О том, что тип p это foo*

anonymous
()
Ответ на: комментарий от anonymous

спасибо. я уж думал,что не ответят. а почему foo нужен для указателя ? почему не int? чем бы они отличались?

class foo{
foo *p;
int *p;

};
 

linuxpc
() автор топика
Ответ на: комментарий от Crocodoom

огромное спасибо. Вы говорите не абы чем, а указателем на объект...

но я могу так

class foo{
foo *p;

};
int main(){
foo obj;
obj.p=0; // это же не адрес объекта
return 0;
}

linuxpc
() автор топика
Ответ на: комментарий от anonymous

ну указатель содержит адрес переменной. адрес-это число. и как притом целое. так почему тогда не int *?

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

ну указатель содержит адрес переменной

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

anonymous
()
Ответ на: комментарий от linuxpc

На самом деле разницы нет, пока ты его не начнешь разыменовывать. int* можно привести к foo*, к void* и к чему угодно.

Deleted
()
Ответ на: комментарий от linuxpc

Это специальный случай, нулевой указатель. Целочисленная константа 0 преобразуется в нулевой указатель по стандарту.

Crocodoom ★★★★★
()

foo *p;// я создал поле класса ,

пока то ты его просто описал, до создания еще не дошло дело, сначала с этим разберись,а потом уже почему не int* , что такое указатель тоже неплохо бы почитать.

jo_b1ack ★★★★★
()
Ответ на: комментарий от linuxpc

ну указатель содержит адрес переменной. адрес-это число. и как притом целое. так почему тогда не int *?

1. Для адресной арифметики. ++p смещает указатель на sizeof(*p), то есть важно знать размер структуры (класса) в байтах. 2. Для контроля за типами, чтобы случайно не разыменовать указатель на foo в переменную типа bar

Crocodoom ★★★★★
()
Ответ на: комментарий от linuxpc

https://timsong-cpp.github.io/cppwp/n4659/basic.compound#3

Every value of pointer type is one of the following:

* a pointer to an object or function (the pointer is said to point to the object or function), or * a pointer past the end of an object ([expr.add]), or * the null pointer value ([conv.ptr]) for that type, or * an invalid pointer value.

anonymous
()
Ответ на: комментарий от Crocodoom

++p смещает указатель на sizeof(*p)

++p делает указатель указывать на следующий элемент массива

anonymous
()
Ответ на: комментарий от Crocodoom

хорошо, тут вроде понятно... тип foo, скажите пожалуйста , сколько байт он занимает в памяти? и где будет хранится ее значение,там же где и разместился класс foo? или все равно?

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

тип foo, скажите пожалуйста , сколько байт он занимает в памяти?

sizeof(foo)

anonymous
()
Ответ на: комментарий от anonymous

если бы я был настолько умным, чтобы читать маны, то не привязывался бы на форумах с просьбой объяснить можно как=то понятней, чем там написанно?

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

и где будет хранится ее значение,там же где и разместился класс foo? или все равно?

в стеке или куче, зависит от того как ты его создашь

jo_b1ack ★★★★★
()
Последнее исправление: jo_b1ack (всего исправлений: 1)
Ответ на: комментарий от jo_b1ack

спасибо

то есть foo как тип не обязывает компилятор выделять память переменной допустим, там же где он ее выделил под класс foo? я правильно понял?

linuxpc
() автор топика
Ответ на: комментарий от Crocodoom

В структуре будет отведено 8 байт под поле адреса.

Но помимо самого указателя, где-то же еще должен хранится тип указателя (и размер типа, на который указывает указатель)

neon1ks ★★
()
Ответ на: комментарий от linuxpc

то есть foo как тип не обязывает компилятор выделять память переменной допустим, там же где он ее выделил под класс foo? я правильно понял?

Сложно понять, то ты написал.

Есть два понятия в C++ definition (определение, реализация) и declaration (объявление, описание).

Если кратко:

  • definition –- переменная создаётся, выделяется память
  • declaration -– происходит только объявление переменной, без выделение памяти, т.е. без её создания.
neon1ks ★★
()
Ответ на: комментарий от linuxpc

то есть foo как тип не обязывает компилятор выделять память переменной допустим, там же где он ее выделил под класс foo?

класс это и есть тип, не понимаю о чем ты говоришь

jo_b1ack ★★★★★
()
Ответ на: комментарий от linuxpc

то есть размер под память для класса или структуры будет всегда больше любого ее поля?

Компилятор выделяет под класс или структуру столько памяти, сколько нужно) Бывает и больше. Размер класса можно узнать, как сказали выше, с помощью sizeof.

На указатель выделяется 8 байт в 64-битной системе. (Хотя, я не до конца знаю, как компилятор работает. Затрудняюсь сказать, где он хранит дополнительную информацию об указателе.)

neon1ks ★★
()
Ответ на: комментарий от neon1ks

ладно, когда я создал и инициализировал поле класса, типа foo a=11; то для компилятора это не говорит о том, что надо выделить память и разместить «a» в той же области памяти где он отвел место под класс foo

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

ну это да, но когда я создаю поле foo a=10; то foo тут тип наверное

a объект типа foo , foo это класс., класс - это абстрактный тип.

jo_b1ack ★★★★★
()
Ответ на: комментарий от linuxpc

ладно, когда я создал и инициализировал поле класса, типа foo a=11; то для компилятора это не говорит о том, что надо выделить память и разместить «a» в той же области памяти где он отвел место под класс foo

это говорит о том что твой «а» будет инициализирован в момент инициализации твоего класса, а где будут находится данные зависит от компилятора

jo_b1ack ★★★★★
()
Ответ на: комментарий от anonymous

Многие declaration это definition

Да, бывает. C++ не простой язык программирования.

neon1ks ★★
()
Ответ на: комментарий от no-such-file

а дальше можете? когда я расширяю пространства имен,на пример foo::void fo(){std::cin>>a }; метода описанного вне класса, то что я два раза тип указываю ? если foo -это тип

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

В С++ есть понятие «область видимости». У класса своя область видимости. С помощью foo:: мы продолжаем область видимости класса.

Так, что func определен именно в классе.

neon1ks ★★
()
Ответ на: комментарий от linuxpc

ну хорошо int foo::func(){}; func метод описанный вне класса

потому что с++ требует реализации методов, если они не виртуальные

jo_b1ack ★★★★★
()
Ответ на: комментарий от jo_b1ack

потому что с++ требует реализации методов, если они не виртуальные

Здесь мы опять возвращаемся к понятиям definition и declaration.

neon1ks ★★
()
Ответ на: комментарий от jo_b1ack

ну хорошо, foo, это тип ,если foo имя класса. значит имя класса это тип.

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

linuxpc
() автор топика
Ответ на: комментарий от neon1ks

имя класса это еще и индификатор, по которому компилятор сможет не спутать переменные этого класса с переменными другого класса... так вроде. а как он это делает? может он располагает переменные(поля) класса foo в одной области памяти, а переменные другого класса fo2 -в другой области памяти. и когда я делаю foo a{11}; то будет присвоенно это значение будет присвоенно именно первому полю int если таких полей было несколько. или два поля foo *p; foo *c; присваивая адрес объекта, он будет также помещен в первое поле класса типа foo. то есть в foo *p; и так как адрес ячейки памяти это всего лишь порядковый номер ее первого байта, то для того чтобы это осуществить надо располагать переменные типа int int и foo foo в одной и той же области памяти. то есть рядом. так?

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

тогда наверное , когда я делаю foo a; где foo это имя класса, то «a» будет размещено в той же области памяти,что и класс с именем foo. вроде я так Вас понял

linuxpc
() автор топика
Ответ на: комментарий от linuxpc

а как он это делает?

С помощью областей видимости. Как реализует компилятор области видимости я не изучал.

тогда наверное , когда я делаю foo a; где foo это имя класса, то «a» будет размещено в той же области памяти,что и класс с именем foo. вроде я так Вас понял

Область памяти и область видимости – это разные вещи. Данные из одной области видимости могут храниться в разных областях памяти.

neon1ks ★★
()
Последнее исправление: neon1ks (всего исправлений: 3)
Ответ на: комментарий от neon1ks

это наверное единственное что я понял, что область видимости и область памяти=это разные вещи

linuxpc
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.