Проблема с указателем

#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);