Как вызвать protected метод c
Перейти к содержимому

Как вызвать protected метод c

  • автор:

[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# применяются следующие модификаторы доступа:

Модификаторы доступа public, protected, internal, private в языке программирования C# и в .NET

  • 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(); // норм >>

Модификаторы доступа в языке программирования C# и в .NET

В классе 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 >

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *