Как вызвать функцию из класса c
Перейти к содержимому

Как вызвать функцию из класса c

  • автор:

Как вызвать определённый метод из другого класса?

Есть два класса. В первом я должен указать какой метод надо выполнить после работы второго класса, а второй, в свою очередь, должен вызвать указанный метод после своей работы.

Это вообще возможно реализовать в C#? Если да, то как?

ZecosMAX's user avatar

Если предполагается хранить методы, которые не принимают аргументов и ничего не возвращают, то будет достаточно Action :

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.11.43304

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

17.7 – Вызов унаследованных функций и переопределение поведения

По умолчанию производные классы наследуют все поведения, определенные в базовом классе. В этом уроке мы более подробно рассмотрим, как выбираются функции-члены, а также как мы можем использовать это для изменения поведения в производном классе.

Вызов функции базового класса

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

Рассмотрим следующий пример:

Эта программа печатает

Когда вызывается derived.identify() , компилятор проверяет, определена ли функция identify() в классе Derived . Ее там нет. Затем он начинает искать наследуемые классы (в данном случае это Base ). Base определил функцию identify() , поэтому компилятор использует ее. Другими словами, Base::identify() использовалась, потому что Derived::identify() не существует.

Это означает, что если поведение, обеспечиваемое базовым классом, достаточно, мы можем просто использовать его.

Переопределение поведения

Однако если бы мы определили Derived::identify() в классе Derived , то использовалась бы эта функция.

Это означает, что мы можем заставить функции работать с нашими производными классами по-другому, переопределив их в производных классах!

В нашем примере выше было бы более правильно, если бы derived.identify() напечатала " I am a Derived ". Давайте изменим функцию identify() в классе Derived , чтобы она возвращала правильный ответ, когда мы вызываем identify() с объектом Derived .

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

Вот тот же пример, что и выше, с использованием новой функции Derived::identify() :

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

Добавление дополнений к существующей функциональности

Иногда мы не хотим полностью заменять функцию базового класса, а вместо этого хотим добавить к ней дополнительный функционал. Обратите внимание, что в приведенном выше примере Derived::identify() полностью скрывает Base::identify() ! Возможно, это не то, что нам нужно. Допускается, чтобы наша производная функция вызывала базовую версию функции с тем же именем (для повторного использования кода), а затем добавляла к ней дополнительный функционал.

Чтобы производная функция вызывала базовую функцию с тем же именем, просто выполните обычный вызов функции, но добавив перед именем функции квалификатор области видимости (имя базового класса и два двоеточия). В следующем примере переопределяется Derived::identify() , поэтому она сначала вызывает Base::identify() , а затем выполняет свои собственные дополнительные действия.

Теперь рассмотрим следующий пример:

Когда выполняется derived.identify() , вызов преобразуется в Derived::identify() . Однако первое, что делает Derived::identify() , – это вызывает Base::identify() , который выводит " I am a Base ". Когда Base::identify() возвращает управление, Derived::identify() продолжает выполнение и печатает " I am a Derived ".

Это должно быть довольно просто. Почему нам нужно использовать оператор разрешения области видимости ( :: )? Если бы мы определили Derived::identify() следующим образом:

Вызов функции identify() без квалификатора разрешения области видимости по умолчанию будет использовать identify() в текущем классе, которой будет Derived::identify() . Это приведет к тому, что Derived::identify() вызовет себя, что приведет к бесконечному циклу!

Есть одна хитрость, с которой мы можем столкнуться при попытке вызвать дружественные функции в базовых классах, такие как operator<< . Поскольку дружественные функции базового класса фактически не являются частью базового класса, использование квалификатора разрешения области видимости не сработает. Вместо этого нам нужен способ временно сделать так, чтобы наш класс Derived выглядел как Base , чтобы можно было вызвать правильную версию функции.

К счастью, это легко сделать с помощью static_cast . Например:

Поскольку Derived «является» Base , мы можем выполнить статическое приведение нашего объекта Derived в Base , чтобы вызывалась соответствующая версия operator<< , которая использует Base .

Как вызвать функцию из класса c

2. Callback’и

#include<iostream>
#include<cmath>
#pragma region
using std::cin;
using std::cout;
using std::endl;
using std::sqrt;
using std::sin;
using std::cos;
#pragma endregion
class AlgebraClass7
public:
void algebraStepennieUravneniya()
void VariantN1();
void N1();
double F, a, b;

AlgebraClass7 example;
example.algebraStepennieUravneniya();

Урок 5. Методы и функции в C#

public Boolean StartService(string serviceName)

static void SayHello()

static void Main(string[] args) static void Square(int a, out int res)

// 1. без ref static void Main(string[] args) static void Plas2(int a)

// 2. с ref static void Main(string[] args) static void Plas2(ref int a)

Как вызвать функцию из класса c

Строка: Form1.Metod("Этот текст из стороннего обьекта") — вызывает ошибку:

An object reference is required for the non-static field, method, or property ‘WindowsFormsApplication1.Form1.Metod(string)’

делать статическим — нежелательно. Этот вариант уже испробован, возможно какие нибудь есть другие варианты? Как обратиться к методам и полям Form1 из другого обьекта?

Ответы

1. передать делегат в конструктор Klass1 (от NIKkakNIK)

2. передать ссылку на Form1 целиком в конструктор Klass1.

3. добавить в Klass1 событие (event) и в коде Form1 подписаться на него.

4. вытащить ссылку на форму из System.Windows.Forms.Application.OpenForms[]

  • Помечено в качестве ответа Abolmasov Dmitry 14 марта 2011 г. 12:54

Спасибо за ответ. Но тут же возникает вопрос — как я понимаю, при запуске программы, уже создается экземпляр Form1. А если я создам новый объект, то строка: this.textBox1.Text = s; эта операция будет применена к новому обьекту и не будет иметь с существующей начальной Form1 — ничего общего — элемент textBox1 — не изменит своего значения в начальной Form1.

Если метод public void metod(string s) — сделать статическим, тут же возникает проблема к обращению элементам окна textBox1, так как в статическом методе по определению нельзя использовать this. А кроме как обращения через this, к элементам окна (editBox1) начальной формы — незнаю. Замкнутый круг. (((((

Возможно есть какая либо переменная, на которую ссылается построенная при запуске программы форма.

А как насчет механизма событий? Применимы ли они в данном случае? Если можно — напишите код — буду очень благодарен!

  • Предложено в качестве ответа NIKkakNIK 14 марта 2011 г. 8:50
  • Помечено в качестве ответа Abolmasov Dmitry 14 марта 2011 г. 12:54

Экземпляр Form1 создается при запуске, если это прописано в функции Main, которая вызывается при запуске всей программы.

Предположим экземпляр действительно создается. Тогда Вам надо передавать указатель на этот объект в конструктор класса Klass1 и сохранять этот указатель внутри нового объекта. После чего можно вызывать все методы этого объекта.

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

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