Это не проблема с "пониманием классов". Вы должны вернуться и понять, что такое «область действия», которая является одной из основных концепций языка C ++.
myStruct aStruct;
принадлежит области действия функции-члена myClass::myClass()
и перестает существовать, когда заканчивается выполнение этой функции. Это совершенно другая область, там не существует переменной aStruct.
void myClass::changeValue()
{
aStruct.width = 23; // aStruct doesn't exist in any available scope
}
Теперь о декларациях:
class myClass
{
private:
struct myStruct
{
int width = 0;
};
Этот код не объявляет хранилище структуры внутри класса myClass
. Он объявляет тип члена myStruct
(который является типом класса) внутри класса myClass
.
(Будьте осторожны с этим соглашением об именах, оно очень запутанно. Рекомендуется использовать заглавные буквы только для членов. Классы рекомендуется использовать только строчные или начинающиеся с заглавной буквы.)
class myClass
{
private:
struct myStruct
{
int width = 0;
};
myStruct aStruct; // myClass got field aStruct
public:
myClass() : aStruct {24} {}
void changeValue();
};
aStruct
здесь относится к закрытой части области видимости класса, которая доступна для всех членов этого класса. myStruct
также объявлен как закрытый, поэтому не может использоваться вне класса, будь то в дочернем классе или просто во внешней области видимости.
myClass() : aStruct {24} {}
Это нетривиальный (определяемый пользователем) конструктор со списком инициализаторов. aStruct
является полем этого класса, поэтому его можно инициализировать значением, подобным этому. Отличается от этой формы
myClass()
{
aStruct.width = 24;
}
В последнем случае aStruct
будет инициализирован сначала (с 0 в поле ширины, как вы указали), и будет вызван его конструктор, затем конструктор myClass
изменит значение своего поле до 24.