[Qt][С++] Как вызвать protected метод в экземпляре класса?
Есть QWizard, созданный в дизайнере. Необходимо сделать некоторые поля в его страницах обязательными для заполнения. Но метод QWizardPage::registerField(), который это делает — protected. В хидере ui-файла страница, на которой нужные поля, создается так:
Инициализируется в функции setupUi:
cfdefinition = new QWizardPage();
При попытке написать что-нибудь вроде переопределения виртуальной функции QWizardPage для этого экземпляра
Ругается, что cfdefinition не является именем класса. Может быть, нужно эту функцию где-нибудь в другом месте переопределить(сейчас пытался в хидере родительского класса — QWizard`a)? Или единственный возможный метод — отдельно проектировать каждую страницу, а потом их в присоединять не в дизайнере, а кодом? Правда, так слишком много придется переделывать
wingear ★★★★
06.09.09 12:33:10 MSD
это вам не скриптовые языки с открытыми классами 😉
> Или единственный возможный метод — отдельно проектировать каждую страницу,
да. или одну универсальную страницу, но всё равно свою, унаследовав от QWizardPage.
> а потом их в присоединять не в дизайнере, а кодом?
зачем кодом? можно и дизайнером.
arsi ★★★★★
( 06.09.09 12:41:51 MSD )
> QWIzardPage *cfdefinition;
> cfdefinition::initializePage() < this->registerField(«name*»,m_ui->lname); >
> Ругается, что cfdefinition не является именем класса.
cfdefinition действительно не является именем класса. Это указатель на объект класса QWIzardPage.
xintrea ★
( 06.09.09 14:25:19 MSD )
Ответ на: комментарий от arsi 06.09.09 12:41:51 MSD
открыл для себя строку контекстного меню «promote to» — оказывается, виджеты можно наследовать от собственных классов:) Правда, QtCreator после обновления ubuntu до кармической коалы постоянно виснет(ставил на старую систему не из репов), сейчас новый накачу и проверю
wingear ★★★★
( 06.09.09 16:27:28 MSD ) автор топика
Компилировать с опцией -Dprotected=public
Reset ★★★★★
( 07.09.09 01:33:25 MSD )
Ответ на: комментарий от Reset 07.09.09 01:33:25 MSD
> Компилировать с опцией -Dprotected=public
tmp_tmp
( 07.09.09 01:50:11 MSD )
Ответ на: комментарий от Reset 07.09.09 01:33:25 MSD
юные программисты на си крест-накрест, бессмысленные и беспощадные =)
nuffsaid
( 07.09.09 03:27:34 MSD )
Ответ на: комментарий от nuffsaid 07.09.09 03:27:34 MSD
Каков вопрос таков и ответ 🙂
Reset ★★★★★
( 07.09.09 11:34:03 MSD )
Ответ на: комментарий от Reset 07.09.09 11:34:03 MSD
собралось, правда все равно поле не выделяется как обязательное. Видимо,в qmake все-таки встроена защита от дурака)
wingear ★★★★
( 07.09.09 18:51:16 MSD ) автор топика
Ответ на: комментарий от wingear 07.09.09 18:51:16 MSD
>собралось, правда все равно поле не выделяется как обязательное.
Ой-ёёё =) Делать «#define protected public» конечно не надо, protected-секции появляются неспроста, можно как раз порушить всю налаженную систему. Да и в остальном тексте такая замена может привести к сюрпризам.
Короче, вот ссылка для примера: http://doc.trolltech.com/4.5/qwizard.html#mandatory-fields Версия QT у тебя какая, кстати? В общем просто не знаю, что там может не работать, если не сможешь повторить пример, свой код давай (не весь, а имеющую отношение к делу часть).
>Видимо,в qmake все-таки встроена защита от дурака)
qmake ничего такого не умеет, это просто система сборки.
Как говорится, no offence, но я бы рекомендовал поизучать C++ отдельно от QT первое время, да и от ОС тоже. Никакая IDE с автодополнением понимания в голове не даст. Я к тому, что это разные базисы, разные наборы концепций. Ты явно что-то торопишься сделать методом кувалды, а с языком C++ это добром не кончится. С QT — тем более. 🙂 Плохо осваивать сразу всё в одной куче.
nuffsaid
( 07.09.09 19:52:50 MSD )
Ответ на: комментарий от nuffsaid 07.09.09 19:52:50 MSD
благодарю. Ссылка не открылась,т.к. нормальный интернет сейчас не работает,а с мобильного доступны только гугол и л.о.р.-) Унаследовал класс от QWizardPage, переопределил метод как public, a потом — promote to и все заработало. Да,я не знаю с++, да и С не особо(только 1 глава Кернигана),но это не для себя,а хоздоговорные работы,в которые неожиданно перешел диплом. Хочется освоить С, vim и openGL, но /me клинический слоупок. Да и вообще не туда поступил
Как использовать protected метод в чужого класса?
Добрый день! Не могу разобраться, как в своём наследующем классе использовать protected метод чужого базового класса.
Например, есть у меня класс MyClass , я наследую класс YourClass с методом
protected void meth1() Я ничего не могу менять в чужом классе, геттеры и сеттеры не помогут, тогда как мне использовать этот метод, какие способы возможны? Спасибо.
Отслеживать
60 10 10 бронзовых знаков
задан 7 авг 2013 в 12:07
21 4 4 бронзовых знака
Опишит подробно кто кого наследует. И из какого места требуется получить доступ к protected методу
7 авг 2013 в 12:36
7 авг 2013 в 14:57
Приведите код. Непонятно, где проблема: protected-методы из объектов порождённых классов всегда можно было использовать без проблем.
7 авг 2013 в 18:28
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
В данном случае есть самый простой вариант — создать в своем классе public метод, который и будет осуществлять вызов protected метод у предка.
Отслеживать
ответ дан 7 авг 2013 в 12:21
Dmitry Lepeshkin Dmitry Lepeshkin
756 4 4 серебряных знака 8 8 бронзовых знаков
Вы можете без проблем использовать методы, помеченные модификатором доступа protected , в классах-наследниках. Для этого и был введен данный модификатор доступа, этим он и отличается от private
Ключевое слово protected является модификатором доступа к члену. Доступ к члену с модификатором protected возможен внутри класса и из производных экземпляров класса.
public class YourClass < protected int YourMethod() < return 1; >> public class MyClass : YourClass < public MyClass () < var a = YourMethod(); // вернет 1 >>
Подробнее почитать про protected тут
Как вызвать protected метод c
Все поля, методы и остальные компоненты класса имеют модификаторы доступа . Модификаторы доступа позволяют задать допустимую область видимости для компонентов класса. То есть модификаторы доступа определяют контекст, в котором можно употреблять данную переменную или метод.
В языке C# применяются следующие модификаторы доступа:
- private : закрытый или приватный компонент класса или структуры. Приватный компонент доступен только в рамках своего класса или структуры.
- private protected : компонент класса доступен из любого места в своем классе или в производных классах, которые определены в той же сборке.
- file : добавлен в версии C# 11 и применяется к типам, например, классам и структурам. Класс или структура с такми модификатором доступны только из текущего файла кода.
- protected : такой компонент класса доступен из любого места в своем классе или в производных классах. При этом производные классы могут располагаться в других сборках.
- internal : компоненты класса или структуры доступен из любого места кода в той же сборке, однако он недоступен для других программ и сборок.
- protected internal : совмещает функционал двух модификаторов protected и internal . Такой компонент класса доступен из любого места в текущей сборке и из производных классов, которые могут располагаться в других сборках.
- public : публичный, общедоступный компонент класса или структуры. Такой компонент доступен из любого места в коде, а также из других программ и сборок.
Стоит отметить, что эти модификаторы могут применяться как к компонентам класса, так и к компонентам структуры за тем исключением, что структуры не могут использовать модификаторы private protected , protected и protected internal , поскольку структуры не могут быть унаследованы.
Все классы и структуры, определенные напрямую вне других типов (классов и структур) могут иметь только модификаторы public , file или internal .
Мы можем явно задать модификатор доступа, а можем его и не указывать:
public class Person < string name; public Person(string name) < this.name = name; >public void Print() => Console.WriteLine($"Name: "); >
Если для компонентов не определен модификатор доступа, то по умолчанию для них применяется модификатор private . Например, в примере выше переменная name неявно будет иметь модификатор private .
Классы и структуры, которые объявлены без модификатора и которые расположены вне других типов, по умолчанию имеют доступ internal , а вложенные классы и структуры, как и остальные компоненты классов/структур имеют модификатор private . Например:
class Phone < struct Camera < >>
Здесь класс Phone не является вложенным ни в один другой класс/структуру, поэтому неявно имеет модификатор internal . А структура Camera является вложенной, поэтому, как и другие компоненты класса, неявно имеет модификатор private
Модификаторы в рамках текущего проекта
Посмотрим на примере и создадим следующий класс State:
class State < // все равно, что private string defaultVar; string defaultVar ="default"; // поле доступно только из текущего класса private string privateVar = "private"; // доступно из текущего класса и производных классов, которые определены в этом же проекте protected private string protectedPrivateVar = "protected private"; // доступно из текущего класса и производных классов protected string protectedVar = "protected"; // доступно в любом месте текущего проекта internal string internalVar = "internal"; // доступно в любом месте текущего проекта и из классов-наследников в других проектах protected internal string protectedInternalVar = "protected internal"; // доступно в любом месте программы, а также для других программ и сборок public string publicVar = "public"; // по умолчанию имеет модификатор private void Print() =>Console.WriteLine(defaultVar); // метод доступен только из текущего класса private void PrintPrivate() => Console.WriteLine(privateVar); // доступен из текущего класса и производных классов, которые определены в этом же проекте protected private void PrintProtectedPrivate() => Console.WriteLine(protectedPrivateVar); // доступен из текущего класса и производных классов protected void PrintProtected() => Console.WriteLine(protectedVar); // доступен в любом месте текущего проекта internal void PrintInternal() => Console.WriteLine(internalVar); // доступен в любом месте текущего проекта и из классов-наследников в других проектах protected internal void PrintProtectedInternal() => Console.WriteLine(protectedInternalVar); // доступен в любом месте программы, а также для других программ и сборок public void PrintPublic() => Console.WriteLine(publicVar); >
Так как класс State не имеет явного модификатора, по умолчанию он имеет модификатор internal , поэтому он будет доступен из любого места данного проекта, однако не будет доступен из других программ и сборок.
Класс State имеет шесть полей для каждого уровня доступа. Плюс одна переменная без модификатора, которая является закрытой (private) по умолчанию. А также определено семь методов с разными модификаторами, которые выводят значения соответствующих переменных на консоль. Поскольку все модификаторы позволяют использовать компоненты класса внутри данного класса, то и все переменные класса, в том числе закрытые, у нас доступны всем его методам, так как все находятся в контексте класса State.
Теперь посмотрим, как мы сможем использовать переменные класса State в другом классе, который, допустим, будет называться StateConsumer и который расположен в том же проекте :
class StateConsumer < public void PrintState() < State state = new State(); // обратиться к переменной defaultVar у нас не получится, // так как она имеет модификатор private и класс StateConsumer ее не видит Console.WriteLine(state.defaultVar); //Ошибка, получить доступ нельзя // то же самое относится и к переменной privateVar Console.WriteLine(state.privateVar); // Ошибка, получить доступ нельзя // обратиться к переменной protectedPrivateVar не получится, // так как класс StateConsumer не является классом-наследником класса State Console.WriteLine(state.protectedPrivateVar); // Ошибка, получить доступ нельзя // обратиться к переменной protectedVar тоже не получится, // так как класс StateConsumer не является классом-наследником класса State Console.WriteLine(state.protectedVar); // Ошибка, получить доступ нельзя // переменная internalVar с модификатором internal доступна из любого места текущего проекта // поэтому можно получить или изменить ее значение Console.WriteLine(state.internalVar); // переменная protectedInternalVar так же доступна из любого места текущего проекта Console.WriteLine(state.protectedInternalVar); // переменная publicVar общедоступна Console.WriteLine(state.publicVar); >>
Таким образом, в классе StateConsumer мы смогли только обратиться к переменным internalVar, protectedInternalVar и publicVar, так как их модификаторы позволяют использовать в данном контексте.
Аналогично дело обстоит и с методами:
class StateConsumer < public void PrintState() < State state = new State(); state.Print(); //Ошибка, получить доступ нельзя state.PrintPrivate(); // Ошибка, получить доступ нельзя state.PrintProtectedPrivate(); // Ошибка, получить доступ нельзя state.PrintProtected(); // Ошибка, получить доступ нельзя state.PrintInternal(); // норм state.PrintProtectedInternal(); // норм state.PrintPublic(); // норм >>
Здесь нам оказались доступны только три метода: PrintInternal, PrintProtectedInternal, PrintPublic, которые имееют соответственно модификаторы internal, protected internal, public.
Модификаторы в рамках сборок
Допустим, у нас есть проект (и соответственно сборка) MyLib, в которой определены три класса:
namespace MyLib; // класс доступен из других сборок public class PublicState < internal void PrintInternal() =>Console.WriteLine(«internal»); protected internal void PrintProtectedInternal() => Console.WriteLine(«protected internal»); public void PrintPublic() => Console.WriteLine(«public»); > // класс доступен только в текущей сборке — по умолчанию internal class DefaultState < >// класс доступен только в текущей сборке internal class InternalState
Здесь классы DefaultState и InternalState имеют модификатор internal , поэтому доступны только в текущем проекте.
Класс PublicState модификатором public доступен из других проектов. Однако его метод PrintInternal() доступен только в текущем проекте. Вне текущего проекта доступен только его метод PrintPublic и PrintProtectedInternal() (доступен в другом проекте только в классах-наследниках).
Допустим, мы подключаем сборку этого проекта MyLib в другой проект, где есть класс StateConsumer:
using MyLib; class StateConsumer < public void PrintState() < // Ошибка DefaultState - по умолчанию internal, поэтому нет доступа DefaultState defaultState = new DefaultState(); // Ошибка InternalState - internal, поэтому нет доступа InternalState internalState = new InternalState(); // норм, PublicState - public, доступен из других программ PublicState publicState = new PublicState(); // Ошибка, нет доступа - метод доступен только в свой сборке publicState.PrintInternal(); // Ошибка, нет доступа - StateConsumer НЕ является классом-наследником от класса PublicState, // поэтому метод не доступен publicState.PrintProtectedInternal(); // нет доступа // норм - общедоступный метод publicState.PrintPublic(); // норм >>
В классе StateConsumer есть доступ только к классу PublicState и его методу PrintPublic , потому что они имеют модификатор public . К остальной функциональности подключенной сборки StateConsumer доступа не имеет.
Благодаря такой системе модификаторов доступа можно скрывать некоторые моменты реализации класса от других частей программы.
Файл как область видимости
C# 11 был добавлен еще один модификатор видимости — file , который применяется к классам, структурам, делегатам, перечислениям, интерфейсам. Типы с этим модификатором могут использоваться только внутри текущего файла кода.
file class Person
Данный модификатор не может использоваться в паре с другими модификаторами.
protected (C++)
Ключевое слово protected указывает доступ к членам класса в списке членов до следующего описателя доступа ( public или) или private конца определения класса. Члены класса, объявленные как protected можно использовать только следующим образом:
- Функции-члены класса, который изначально объявил эти элементы.
- Дружественные элементы класса, который изначально объявил эти элементы.
- Классы, производные с использованием открытого или защищенного доступа от класса, который изначально объявил эти элементы.
- Прямые производные с использованием закрытого доступа классы, которые также имеют закрытый доступ к защищенным элементам.
При выполнении имени базового класса ключевое слово указывает, что общедоступные и защищенные члены базового класса protected защищены членами производных классов.
Защищенные члены не так закрыты private , как члены, которые доступны только членам класса, в котором они объявлены, но они не как открытые public , как члены, которые доступны в любой функции.
Защищенные члены, которые также объявлены static как доступны любому другому или члену функции производного класса. Защищенные члены, которые не объявлены как static доступны для друзей и функций-членов в производном классе только через указатель на, ссылку на или объект производного класса.
Специально для /clr
В типах СРЕДЫ CLR описатель доступа C++ ключевое слово ( public , private и protected ) может повлиять на видимость типов и методов в отношении сборок. Дополнительные сведения см. в разделе «Члены контроль доступа».
Файлы, скомпилированные с помощью /LN , не влияют на это поведение. В этом случае все управляемые классы (открытые или закрытые) будут видны.
КОНЕЦ специально для /clr
Пример
// keyword_protected.cpp // compile with: /EHsc #include using namespace std; class X < public: void setProtMemb( int i ) < m_protMemb = i; >void Display() < cout protected: int m_protMemb; void Protfunc() < cout > x; class Y : public X < public: void useProtfunc() < Protfunc(); >> y; int main() < // x.m_protMemb; error, m_protMemb is protected x.setProtMemb( 0 ); // OK, uses public access function x.Display(); y.setProtMemb( 5 ); // OK, uses public access function y.Display(); // x.Protfunc(); error, Protfunc() is protected y.useProtfunc(); // OK, uses public access function // in the derived class >