Что происходит при инициализации этого объекта? - PullRequest
2 голосов
/ 30 ноября 2009

Я выполняю инициализацию объекта, как показано в коде ниже:

namespace PatternPractice
{
 public class TestClass
 {
    private DecoratorClass decoratorClass;
    public TestClass()
    {

    }

    public void addTest()
    {
        decoratorClass = new DecoratorClass();
        testMethod(decoratorClass);
    }

    public void testMethod(DecoratorClass d)
    {
        Console.WriteLine("Am doing to explain my question.");
    }
   }
}

У меня есть следующие вопросы:

а. Что такое переменная decoratorClass? Ссылка на область памяти, где создается эта переменная, или что-то еще?

б. В методе addTest () я инициализирую этот decoratorClass, что теперь стало, ссылка на объект или что-то еще?

с. Если это становится ссылкой на объект, то почему мы используем ref в параметрах, которые мы хотим передать по ссылке. Этот вопрос не имеет смысла, если decoratorClass не является ссылкой, а что-то еще.

д. В методе testMethod () я знаю, что копия decoratorClass создается и передается, опять же, это ссылка или что-то еще?

Я немного озадачен тем, как все это происходит во время выполнения (ASP.NET или JVM и т. Д.) И в основном связано с созданием объектов в памяти.

Есть ли какая-либо статья, которая может объяснить, как создание объектов происходит во время выполнения и как они выделяются в памяти.

Спасибо за помощь.

Ответы [ 3 ]

2 голосов
/ 30 ноября 2009

Базовая концепция типа значения и ссылочного типа.

Любой тип переменной (будь то тип значения или ссылочный тип) помещается в стек при объявлении.

Однако, разница между ними заключается в том, что в случае типов значений значение объекта сохраняется в стеке. Принимая во внимание, что в случае ссылочных типов адрес кучи сохраняется в стеке.

Итак, рассмотрим утверждения:

int a;
DecoratorClass decoratorClass;

Теперь, когда выполняются эти операторы, это стек:

STACK:

Variable        Value
a                 0     // Since ints are assigned to 0 by default
decoratorClass    NULL

Теперь, если вы попытаетесь получить доступ к decoratorClass, например, decoratorClass.memberVariable = xyz; и т. Д., Тогда вы получите исключение NullPointerException. Это потому, что decoratorClass объявляется только не инициализированным. Он будет инициализирован только при вызове конструктора.

Итак, когда запускается приведенная ниже инструкция:

decoratorClass = new DecoratorClass();

1) Память распределяется в куче в определенном месте (адресе). Объем памяти, выделяемый в байтах, зависит от определения класса (переменные-члены)

HEAP:

xEEEE00
xEEEE01
xEEEE02
xEEEE03

2) Теперь, поскольку объекту выделена некоторая память, стек будет обновляться с помощью адреса памяти

STACK:

    Variable        Value
    a                 0     // Since ints are assigned to 0 by default
    decoratorClass  xEEEE00

Теперь, если вы попытаетесь получить доступ к decoratorClass.memberVariable, вы не получите исключение NullPointer, поскольку экземпляр инициализирован и в стеке назначено место в памяти.

СЕЙЧАС ОТВЕТИТ НА ВАШИ ВОПРОСЫ:

a. Что такое переменная decoratorClass? Ссылка на область памяти, где создается эта переменная, или что-то еще? И b. В методе addTest () я инициализирую этот decoratorClass, каким он стал теперь, ссылкой на объект или чем-то еще?

Ans: Переменная decoratorClass будет помещена в стек при выполнении оператора объявления. Его значения в стеке (который должен быть адресом в куче) будут нулевыми, так как память еще не распределена в куче. Память будет выделяться в куче при вызове конструктора. Стек теперь будет содержать адрес в куче

Позвольте мне ответить d, прежде чем я отвечу c, так как считаю, что вам будет проще понять этот путь.

d. В методе testMethod () я знаю, что копия decoratorClass создана и передана, опять же, это ссылка или что-то еще?

Ans: С объяснением, которое я дал выше, в методе testMethod (DecoratorClass d) d является локальной переменной для testMethod (). Но каково значение в d (то есть значение в стеке)? Это адрес decoratorClass. Таким образом, локальная переменная d указывает на ту же кучу, и, следовательно, доступ к memberVariable of d будет иметь то же значение, что и доступ к memberVariable для decoratorClass.

Теперь, если вы создадите новый DecoratorClass и назначите его для d, он НЕ ИЗМЕНЯЕТ decoratorClass. Так что d может указывать на EEEE06, но decoratorClass все равно будет указывать на EEEE00.

Теперь давайте перейдем к c.

c. Если это становится ссылкой на объект, то почему мы используем ref в параметрах, которые мы хотим передать по ссылке. Этот вопрос не имеет смысла, если decoratorClass не является ссылкой, а что-то еще. Ans: Давайте рассмотрим тот же метод testMethod (ref DecoratorClass d). Поскольку вы передаете d как ref, это уже не локальная переменная, а та же самая переменная.

Теперь, если вы создадите новый DecoratorClass и назначите его для d, он изменит DecoratorClass. Таким образом, d будет указывать на EEEE06, но будет иметь эффект decoratorClass, также указывающего на EEEE06, поскольку обе переменные в стеке являются одинаковыми.

Для получения более подробной информации об объекте pass по ref v / s, проверьте объект pass по значению Память игр

Надеюсь, я достаточно сложен.

Ура!

1 голос
/ 30 ноября 2009

а. Если DecoratorClass является классом - тогда да, это ссылка. Если это структура, то класс TestClass содержит весь экземпляр DecoratorClass.

б. Смотри "а"

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

д. Если DecoratorClass является классом, то только ссылка на него копируется и передается в метод testMethod. Если структура - тогда весь экземпляр копируется и передается в testMethod

0 голосов
/ 30 ноября 2009

а. В верхней части вашего класса Decoratorclass находится просто переменная без выделения памяти. Объекты создаются в куче, а не в стеке.

б. В методе testmethod вы теперь выделили память для этого объекта DecoratorClass в куче, а ваша переменная decoratorClass становится ссылкой на эту память, выделяемую в куче.

с. Параметры ref в основном используются для передачи типов значений, таких как (int, long, char и т. Д.). Как ответ выше, если вы хотите изменить то, на что ваш объект ссылается в памяти, вы можете передать объект (ссылочный тип), используя Ref. Теперь вы измените то, на что ссылается этот объект.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...