#c #pointers #pass-by-reference #pass-by-value
#c #указатели #передача по ссылке #передача по значению
Вопрос:
У меня возникли проблемы с корректной работой моих указателей. В моем основном файле я заявляю
Analysis2 analysis = Analysis2();
MaxResults maxresults = MaxResults( analysis);
Теперь в моем классе maxResults я хочу указать на analysis, чтобы при изменении какой-либо из его переменных я все равно получал правильное значение. Прямо сейчас я объявляю конструктор в заголовке maxResults как
MaxResults(Analysis2 analysis);
Analysis2 * analysis2;
И в классе maxResults
MaxResults(Analysis2 analysis)
{
analysis2 = analysis;
}
Когда я пытаюсь получить доступ к вещам из analysis, которые изменились, analysis2, похоже, не успевает. Как мне это исправить, и есть ли простой способ запоминать указатели, ссылки и разыменования в будущем?
Комментарии:
1. Какие из них должны быть указателями? Пожалуйста, попробуйте опубликовать что-нибудь, отдаленно напоминающее C .
2. Я хочу, чтобы анализ 2 указывал на анализ (и, следовательно, указывал на все изменения, внесенные после этого назначения)
Ответ №1:
Если вы хотите MaxResults
сохранить указатель на Analysis2
объект, вы должны сделать это следующим образом:
class MaxResults {
public:
MaxResults(Analysis* an) : analysis(an) {}
private:
Analysis* analysis;
};
и сконструируйте это следующим образом:
Analysis2 analysis = Analysis2();
MaxResults maxresults = MaxResults( amp;analysis);
Обратите внимание на использование оператора address-of (amp;) для записи адреса analysis
и передачи его в качестве указателя в MaxResults
конструктор, который сохраняет указатель в элементе (используя список инициализации, что более или менее эквивалентно выполнению analysis = an
в теле конструктора, на случай, если :
синтаксис для вас новый).
Для дальнейшего чтения взгляните на ссылки (конечно, как только вы лучше поймете, что такое указатели). В этом случае, вероятно, было бы предпочтительнее использовать ссылки.
Комментарии:
1. Я бы не рекомендовал использовать вызов по ссылке и удерживать объект дольше, чем сам функциональный вызов. Использование указателей здесь совершенно нормально.
Ответ №2:
Я не совсем уверен, как это компилируется; это не должно. Проблема в вашем конструкторе.
Во-первых, если ваш конструктор просто принимает Analysis2
параметр, этот параметр передается по значению; объект всегда копируется. Указатель никак не может указывать на фактический объект, который был передан, поскольку ваш конструктор получает только его копию. Вам нужно использовать ссылочный параметр:
MaxResults(Analysis2amp; analysis);
Во-вторых, вы не можете напрямую назначить объект указателю на этот объект. Для получения адреса объекта необходимо использовать amp;
оператор.
MaxResults(Analysis2amp; analysis)
{
analysis2 = amp;analysis;
}
На несвязанном примечании: хорошим стилем является использование списка инициализаторов элементов для конструктора.
MaxResults(Analysis2amp; analysis)
: analysis2(amp;analysis)
{
}
Комментарии:
1. Он компилировался, пока я не понял, что analysis2 не отражает анализ, затем, когда я изменил код на то, что вы видите выше, он сломался, и я просто не знал, как правильно назначить мои указатели
2. А, понятно. Да, это сломалось, потому что тип
analysis2
— указатель на Analysis2, а типanalysis
— просто Analysis2. Компилятор не будет автоматически преобразовывать из одного в другой; вам нужно использовать операторы. Оператор, который переходит от объекта к указателю на этот объект, являетсяamp;
; другое направление —*
. (Примечание: технически это не преобразования, но такова общая идея.)3. Я бы не стал так смешивать ссылки и указатели. Просто используйте указатели и попросите клиента ввести дополнительный
amp;
символ.4. Я лично кодирую в стиле, где указатель в параметре означает, что с памятью каким-то образом манипулируют (т. Е. получателю может потребоваться освободить переданный объект, или это может быть массив или другая арифметика указателя). Поэтому я предпочел бы увидеть ссылку здесь, особенно потому, что (я предполагаю) нет причин для того, чтобы элемент данных был нулевым. И поскольку вы не можете скопировать класс со ссылочным элементом данных, мое личное мнение заключается в том, что ссылочный параметр с элементом данных указателя является наиболее разумным способом реализации этого.
Ответ №3:
При вызове MaxResults maxresults = MaxResults(analysis);
ваш конструктор получает копию analysis
. Вам нужно передать ссылку на analysis
, чтобы конструктор получил адрес, который он может сохранить в указателе. Таким образом, maxresults
будет получен указатель на исходный объект, а не просто копия исходного объекта.
Сделайте что-то подобное в заголовке:
MaxResults(Analysis2 *analysis);
Analysis2* analysis2;
Сделайте это в определении класса:
MaxResults(Analysis2 *analysis)
{
analysis2 = analysis;
}
И создайте объекты таким образом:
Analysis2 analysis = Analysis2();
MaxResults maxresults = MaxResults(amp;analysis);