Я учусь и немного играю с указателями и адресами памяти.
Дело в том, что я пробовал делать некоторые перемещения с экземплярами внутри массивов и получать их адреса в памяти, но не могу понять, почему следующий случай не выполняется, если они должны указывать на один и тот же экземпляр, поэтому я должен получить тот же адрес.
Мне бы очень хотелось знать, почему это происходит, поскольку я думаю, что, вызывая адрес, на который указывает указатель, связанный с массивом, я буду вызывать тот же адрес памяти исходного экземпляра, а не другой адрес массива.
Если с моим вопросом возникнет какая-либо путаница или недопонимание, пожалуйста, не стесняйтесь спрашивать что-нибудь, чтобы понять мою проблему. Я действительно хочу знать, почему это происходит.
#include<iostream>
#include<string.h>
using namespace std;
class Student {
int age;
string name;
// methods and public variables
public: Student(int _age, string _name) {
this -> age = _age;
this -> name = _name;
}
// getters & setters not appearing in this problem
};
int main() {
Student a1(12, "qwe");
Student a2(15, "rty");
Student a3(17, "zxc");
Student * p = & a1;
// array of instances
Student students[] = {
a1,
a2,
a3
};
// arrays with pointers
Student * studentPtr1 = students;
Student * studentPtr2 = & students[0];
// this two are the same memory addres
cout << "&a1 --> " << & a1 << endl;
cout << "p --> " << p << endl;
// the rest of these memory addresses are different from a1 but are the same memory address as each other
cout << "&(students[0]) --> " << & (students[0]) << endl;
cout << "&(students) :" << & (students) << endl;
cout << "&(*studentPtr1) --> " << & ( * studentPtr1) << endl;
cout << "&(*studentPtr2) --> " << & ( * studentPtr2) << endl;
cout << "studentPtr2 --> " << studentPtr2 << endl;
// if students[0] is a1 why if a try to get his memory address i get a different one ?.
// &(students[0]) == &a1 ---> false (why??).
return 0;
}
&a1 --> 0x7ffeb1d77e30
p --> 0x7ffeb1d77e30
&(students[0]) --> 0x7ffeb1d77ec0
&(students) :0x7ffeb1d77ec0
&(*studentPtr1) --> 0x7ffeb1d77ec0
&(*studentPtr2) --> 0x7ffeb1d77ec0
studentPtr2 --> 0x7ffeb1d77ec0
объект, хранящийся в массиве, не может быть тем же объектом, которого нет в массиве. С++ имеет семантику значений. Student students[] = { a1, a2, a3 };
делает копии
ОТ: std::string
из <string>
. <string.h>
это нечто совершенно другое
Вы можете иметь массив указателей на объекты, хранящиеся в другом месте, и иметь возможность очень быстро добавлять и перемещать эти указатели, почти все остальное, что вы будете делать с массивом, будет медленнее, потому что ЦП должен использовать указатель, чтобы найти, где находится объект. действительно есть, и тогда, скорее всего, придется загрузить его в кеш. Но если объекты находятся непосредственно в массиве, все они располагаются в памяти по прямой линии, а современные процессоры отвратительно хороши в прогнозировании, опережающем чтении, кэшировании и вообще очень быстры, когда данные расположены по прямой линии.
если студенты[0] равны a1... Это не так. Это копия А1.
Эта функция-член deleteStudent
— не очень хорошая идея. Если у вас есть указатель на объект Student
, вы обычно удаляете объект Student
с помощью delete ptr;
.
Какая ссылка научила вас использовать синтаксис this->
? Вам это не нужно. Если вы собираетесь его использовать, вам следует применять его повсюду; быть последовательным. Ваш конструктор должен использовать список инициализации вместо this->
.
Ваш деструктор должен быть пустым. У вас нет динамических переменных и ничего, что можно было бы очистить. Оператор delete
используется для элементов, размещенных в динамической памяти, которой у вас нет. Вы понятия не имеете, использовал ли Пользователь вашего класса локальное или динамическое размещение. Итак, избавьтесь от утверждения delete this
.
Вам следует переместить свой метод setName()
в раздел геттеров и сеттеров, поскольку это сеттер.
К вашему сведению, передайте переменную std::string
по ссылке или, если она не записана, передайте ее по ссылке const
. В противном случае компилятор создаст копию строки вызывающего объекта и передаст ее вашим методам. Это много ненужного копирования, особенно для больших строк.
student[0]
и a1
имеют одинаковое значение, это правда. Но они хранятся в разных местах, поэтому и адреса у них разные.
Вот еще один пример
int a = 1;
int b = 2;
int c = 3;
int student[3] = { a, b, c };
Теперь student[0] == a
но &student[0] != &a
. Тот факт, что student[0]
и a
имеют одинаковое значение, не означает, что у них одинаковый адрес. Это (я надеюсь) очевидно, когда a
и student[0]
являются целыми числами, но это так же верно, когда они являются объектами.
или даже проще int b = a;
какой еще результат вы ожидали и почему?