Подтвердить что ты не робот

Что такое ранняя (статическая) и поздняя (динамическая) привязка в С++?

Как выглядит раннее и позднее связывание в С++? Можете ли вы привести пример?

Я читал, что перегрузка функции - это раннее связывание, а виртуальные функции - поздняя привязка. я читать, что "ранняя (или статическая) привязка относится к привязке времени компиляции и позднему (или динамическому) привязке относится к привязке времени выполнения".

4b9b3361

Ответ 1

Вы читаете правильно. Основной пример может быть задан с помощью:

using FuncType = int(*)(int,int); // pointer to a function
                                  // taking 2 ints and returning one.

int add(int a, int b) { return a + b; }
int substract(int a, int b) { return a - b; }

Статическое связывание - это когда привязка известна во время компиляции:

int main() {
    std::cout << add(4, 5) << "\n";
}

не оставляет места для динамического изменения операции и поэтому статически привязано.

int main() {
    char op = 0;
    std::cin >> op;

    FuncType const function = op == '+' ? &add : &substract;

    std::cout << function(4, 5) << "\n";
}

тогда как здесь, в зависимости от ввода, получается 9 или -1. Это динамически связано.

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

struct Function {
    virtual ~Function() {}
    virtual int doit(int, int) const = 0;
};
struct Add: Function {
    virtual int doit(int a, int b) const override { return a + b; } 
};
struct Substract: Function {
    virtual int doit(int a, int b) const override { return a - b; } 
};

int main() {
    char op = 0;
    std::cin >> op;

    std::unique_ptr<Function> func =
        op == '+' ? std::unique_ptr<Function>{new Add{}}
                  : std::unique_ptr<Function>{new Substract{}};

    std::cout << func->doit(4, 5) << "\n";
}

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

Ответ 2

Это относится ко всем объектно-ориентированным языкам, а не только к С++.

Статический, привязка времени компиляции проста. Там нет полиморфизма. Вы знаете тип объекта, когда пишете и компилируете и запускаете код. Иногда собака просто собака.

Динамическое связывание времени выполнения - это полиморфизм.

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

Ответ 3

Статическое связывание: если вызов функции известен во время компиляции, то он известен как статическая привязка. в статическом типе привязки объекта объекта, соответственно, называется подходящая функция. как показано в примере ниже obj_a.fun(), здесь obj_a имеет класс A, поэтому вызывается fun() класса.

#include<iostream>
using namespace std;
class A{
public:
void fun()
{cout<<"hello world\n";}

};
class B:public A{
public:
void show()
{cout<<"how are you ?\n";}

};

int main()
{
A obj_a;           //creating objects
B obj_b;
obj_a.fun();       //it is known at compile time that it has to call fun()
obj_b.show();     //it is known at compile time that it has to call show()
return 0;
}

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

#include<iostream>
using namespace std;

class car{
public:
    virtual void speed()
     {
      cout<<"ordinary car: Maximum speed limit  is 200kmph\n";
     }
};
class sports_car:public car{
  void speed()
     {
      cout<<"Sports car: Maximum speed is 300kmph\n";
     }
};

int main()
{
car *ptr , car_obj;      // creating object and pointer to car
sports_car   sport_car_obj;  //creating object of sport_car
ptr = &sport_car_obj;      // assigining address of sport_car to pointer 
                             //object of car 
 ptr->speed();   // it will call function of sports_car

return 0;
}

если мы удалим виртуальное ключевое слово из класса автомобиля, он вызовет функцию класса автомобиля. но теперь он вызывает функцию скорости класса sport_car. это динамическое связывание, поскольку во время функции, вызывающей содержимое указателя, не является типом указателя. поскольку ptr имеет тип автомобиля, но имеет адрес sport_car, поэтому вызывается sport_car speed().