Как сделать общую переменную для всех объектов класса

Обновлено: 04.07.2024

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

Локальные и глобальные переменные

Время жизни объекта может быть глобальным и локальным.

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

Локальными называют объекты, объявление которых дано внутри блока или функции. Эти объекты доступны только внутри того блока, в котором они объявлены. Объектам с локальным временем жизни выделяется новая ячейка памяти каждый раз при осуществлении описания внутри блока. Когда выполнение блока завершается, память, выделенная под локальный объект, освобождается, и объект теряет своё значение.

Область видимости локальной переменной k - функция autofunc() . Каждый раз при входе в функцию с идентификатором k ассоциируется некоторая ячейка памяти, в которую помещается значение равное 1.

Локальная переменная k

Результат выполнения программы

Та же программа, но с использованием глобального объекта

Глобальная переменная k

Результат выполнения программы

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

Использование глобальных переменных


Результат выполнения

Модификация объектов

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


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


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

Модификатор extern

Пример окна проекта, состоящего из двух файлов


Модификатор static позволяет связать с идентификатором фиксированный адрес (ячейку памяти). Если объект расположен по некоторому фиксированному адресу, то он называется статическим .

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

Переменная k в функции autofunc() зафиксирована в оперативной памяти. Инициализация k проводится только один раз — при первом вызове функции. При повторном обращении к функции autofunc() инициализация переменной k не будет производиться. Значение переменной k и ее адрес сохраняются в оперативной памяти, однако эта переменная не будет доступна из других функций.

Статическая переменная k

Результат выполнения программы


Модификатор register предназначен для того, чтобы поместить переменную в один из регистров общего назначения центрального процессора при наличии свободного регистра. Благодаря этому повышается скорость работы с данными. Это необходимо для создания управляющих программ, где требуется высокая скорость обработки данных.

Что такое переменная экземпляра класса Java и с чем ее едят? Переменные, которые имеют глобальный охват и локальный, в чем различие? Обо все этом в нашем новом уроке на примере кода из предыдущей статьи.

В предыдущем разделе мы говорили о переменных внутри методов. Переменные, которые вы устанавливаете внутри методов, доступны только этим методам. Они не доступны для других методов. То есть, они имеют локальный охват.

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

Добавьте следующие четыре строки в ваш новый класс Sales из предыдущего урока:

Мы устанавливаем четыре переменные String (четыре строковых экземпляра). Как следует из названий экземпляров нашего класса Sales, строки будут содержать имя работника, его должность, количество продаж и его зарплату.

Эти четыре экземпляра класса будут доступны для всех методов, которые мы напишем в этом классе, и они не будут локальными для какого-либо одного метода. То есть, они имеют глобальный охват.

Чтобы увидеть, насколько они глобальны, вернитесь в класс Branch, класс с методом main. Добавьте следующую строку кода, чтобы создать новый объект класса Sales:

Это то же самое, что мы делали в предыдущем разделе - использовали ключевое слово new для создания нового объекта. Имя объекта будет aWorker, и оно имеет тип от Sales, который является нашим классом.

В следующей строке введите имя переменной (aWorker), а затем точку. После NetBeans отобразит всплывающий список методов и свойств, доступных вашему объекту:

Четыре экземпляра, которые мы настроили, находятся в списке. Это не методы, а то, что называется свойством. Тот факт, что они вообще есть в списке, означает, что они имеют глобальный охват. Если бы у них был локальный охват, их бы не было в списке.

Вы можете установить значения для свойств. Попробуйте это: добавьте следующий выделенный код в ваш метод main (выделено синим цветом):

Итак, четыре переменные, которые мы установили, теперь доступны для обоих классов.

Однако это считается правилом плохого тона в программировании, делать подобным образом экземпляры класса. Мы склонны терять представление о том, какие значения хранятся в них, и, следовательно, это значительно усложняет отладку кода. Считается более правильным сужать область видимости переменных экземпляра.

Чтобы сделать переменную экземпляра доступной только для определенного класса, вы добавляете ключевое слово в Java private непосредственно перед объявлением экземпляра. Измените код в классе Sales на это:

Теперь только код в классе Sales может видеть эти переменные экземпляра класса. Чтобы проверить, вернитесь к методу main, и вы увидите следующие предупреждения и красные подчеркивания:

Удалите три строки снизу. Введите aWorker, а затем снова точку, чтобы увидеть всплывающий список NetBeans:

Как видите, четыре переменные экземпляра нашего класса исчезли. Они исчезли, потому что у них больше нет глобальной области видимости, и, следовательно, их нельзя увидеть из класса Branch. (Красное подчеркивание говорит лишь о том, что строка еще не дописана и Java-программа расценивает это как ошибку.)

В следующем уроке вы узнаете о том, что называется конструктором класса.

Описанием объекта является класс , а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке, у которого есть имя, возраст, какие-то другие характеристики. То есть некоторый шаблон - этот шаблон можно назвать классом. Конкретное воплощение этого шаблона может отличаться, например, одни люди имеют одно имя, другие - другое имя. И реально существующий человек (фактически экземпляр данного класса) будет представлять объект этого класса.

В принципе ранее уже использовались классы. Например, тип string , который представляет строку, фактически является классом. Или, например, класс Console , у которого метод WriteLine() выводит на консоль некоторую информацию. Теперь же посмотрим, как мы можем определять свои собственные классы.

По сути класс представляет новый тип, который определяется пользователем. Класс определяется с помощью ключевого слова сlass :

После слова class идет имя класса и далее в фигурных скобках идет собственно содержимое класса. Например, определим в файле Program.cs класс Person, который будет представлять человека:

Однако такой класс не особо показателен, поэтому добавим в него некоторую функциональность.

Поля и методы класса

Класс может хранить некоторые данные. Для хранения данных в классе применяются поля . По сути поля класса - это переменные, определенные на уровне класса.

Кроме того, класс может определять некоторое поведение или выполняемые действия. Для определения поведения в классе применяются методы.

Итак, добавим в класс Person поля и методы:

В данном случае в классе Person определено поле name , которое хранит имя, и поле age , которое хранит возраст человека. В отличие от переменных, определенных в методах, поля класса могут иметь модификаторы, которые указываются перед полем. Так, в данном случае, чтобы все поля были доступны вне класса Person поля определены с модификатором public .

При определении полей мы можем присвоить им некоторые значения, как в примере выше в случае переменной name . Если поля класса не инициализированы, то они получают значения по умолчанию. Для переменных числовых типов это число 0.

Также в классе Person определен метод Print() . Методы класса имеют доступ к его поля, и в данном случае обращаемся к полям класса name и age для вывода их значения на консоль. И чтобы этот метод был виден вне класса, он также определен с модификатором public .

Создание объекта класса

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

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

Конструктор по умолчанию

Если в классе не определено ни одного конструктора (как в случае с нашим классом Person), то для этого класса автоматически создается пустой конструктор по умолчанию, который не принимает никаких параметров.

Теперь создадим объект класса Person:

Для создания объекта Person используется выражение new Person() . В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект, и через эту переменную мы можем использовать данный объект и обращаться к его функциональности.

Обращение к функциональности класса

Для обращения к функциональности класса - полям, методам (а также другим элементам класса) применяется точечная нотация точки - после объекта класса ставится точка, а затем элемент класса:

Например, обратимся к полям и методам объекта Person:

Консольный вывод данной программы:

Константы классы

Кроме полей класс может определять для хранения данных константы. В отличие от полей из значение устанавливается один раз непосредственно при их объявлении и впоследствии не может быть изменено. Кроме того, константы хранят некоторые данные, которые относятся не к одному объекту, а ко всему классу в целом. И для обращения к константам применяется не имя объекта, а имя класса:

Здесь в классе Person определена константа type , которая хранит название класса:

Название класса не зависит от объекта. Мы можем создать много объектов Person, но название класса от этого не должно измениться - оно относится ко всем объектам Person и не должно меняться. Поэтому название типа можно сохранить в виде константы.

Стоит отметить, что константе сразу при ее определении необходимо присвоить значение.

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

Однако если мы хотим обратиться к константе вне ее класса, то для обращения необходимо использовались имя класса:

Таким образом, если необходимо хранить данные, которые относятся ко всему классу в целом

Добавление класса в Visual Studio

Обычно классы помещаются в отдельные файлы. Нередко для одного класса предназначен один файл. И Visual Studio предоставляет по умолчанию встроенные шаблоны для добвления класса.

Для добавления класса нажмем в Visual Studio правой кнопкой мыши на название проекта:

В появившемся контекстном меню выберем пункт Add -> New Item. (или Add -> Class. )

В открывшемся окне добавления нового элемента убедимся, что в центральной части с шаблонами элементов у нас выбран пункт Class . А внизу окна в поле Name введем название добавляемого класса - пусть он будет назваться Person :

В качестве названия класса можно вводить как Person, так и Person.cs. И после нажатия на кнопку добавления в проект будет добавлен новый класс:

В файле Person.cs определим следующий код:

Здесь определен класс Person с одним полем name и методом Print.

В файле Program.cs , который представляет основной файл программы используем класс Person:

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

Программа на C++ состоит из различных сущностей, таких как переменные, функции, типы и пространства имен. Каждая из этих сущностей должна быть объявлена , прежде чем их можно будет использовать. В объявлении указывается уникальное имя сущности, а также сведения о ее типе и других характеристиках. В C++ точка, в которой объявлено имя, является точкой, в которой он становится видимым для компилятора. Нельзя ссылаться на функцию или класс, объявленные в более поздней точке в единице компиляции. Переменные должны быть объявлены как можно ближе до точки, в которой они используются.

В следующем примере показаны некоторые объявления:

В строке 5 main объявлена функция. В строке 7 const pi объявлена и const переменная с именем. В строке 8 целое число i объявляется и инициализируется значением, созданным функцией f . Имя f является видимым для компилятора из-за f в строке 3.

В строке 10 str объявлена переменная типа с именем std::string . Имя std::string является видимым, так как оно представлено в string std::string , который объединяется с исходным файлом в строке 1. std пространство имен, в котором string объявлен класс.

В строке 11 возникает ошибка, так как имя j не было объявлено. Объявление должно предоставлять тип, в отличие от других языков, таких как JavaScript. В строке 12 auto используется ключевое слово, которое указывает компилятору вывести тип k на основе значения, с которым он инициализируется. Компилятор в этом случае выбирает int тип.

Область видимости объявления

Имя, введенное в объявлении, допустимо в пределах области , в которой происходит объявление. В предыдущем примере переменные, объявленные внутри main функции, являются main . Можно объявить другую переменную i , именованную за пределами Main, в i , и это будет отдельная сущность. Однако такое дублирование имен может привести к путанице и ошибкам программиста, и их следует избегать. В строке 21 класс C объявляется в области видимости пространства имен N . Использование пространств имен помогает избежать конфликтов имен. Большинство имен стандартных библиотек C++ объявляются в std пространстве имен. Дополнительные сведения о взаимодействии правил определения области с объявлениями см. в разделе Scope.

Определения

Некоторые сущности, включая функции, классы, перечисления и константные переменные, должны быть определены и объявлены. Определение предоставляет компилятору все сведения, необходимые для создания машинного кода, когда сущность используется позже в программе. В предыдущем примере строка 3 содержит объявление для функции, f но f функции предоставляется в строках с 15 по 18. В строке 21 класс C объявлен и определен (хотя в соответствии с определением класс не выполняет никаких действий). Константная переменная должна быть определена, иными словами, которой было присвоено значение, в той же инструкции, в которой она объявлена. Объявление встроенного типа, например int , автоматически определяется определением, так как компилятор знает, сколько пространства нужно выделить.

В следующем примере показаны объявления, которые также являются определениями:

Ниже приведены некоторые объявления, которые не являются определениями.

Определения типов и операторы using

В более старых версиях C++ typedef ключевое слово используется для объявления нового имени, которое является typedef для другого имени. Например, типом std::string является другое имя для std::basic_string . Должно быть очевидно, почему программисты используют имя typedef, а не фактическое имя. В современных C++ using ключевое слово предпочтительнее typedef , но идея одинакова: новое имя объявляется для сущности, которая уже объявлена и определена.

Члены статических классов

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

объявления extern

Программа на C++ может содержать более одной единицы компиляции. Чтобы объявить сущность, определенную в отдельной единице компиляции, используйте extern ключевое слово. Сведения в объявлении достаточны для компилятора, но если определение сущности не удается найти на шаге компоновки, то компоновщик вызовет ошибку.

Читайте также: