ссылка и указатель используются для полиморфизма? [Дубликат]

0

Я изучаю c++. У меня проблема с постоянным полиморфизмом времени? почему нам нужно использовать ссылку/указатель, когда такую же работу можно сделать, создав объект класса?

'для:

class A{
private:
    int p;
public:
    A(){}   //ctor
    void Print(){}
    void display(){}
    void showrecord(){}
} 
class B:public A
{
Private:
     int q;
public:
    B(){}    //ctor
    void Print(){}  
    void displayrecord(){}
}

теперь в приведенном выше случае я могу получить доступ к любому методу класса B, используя его объект и метод класса b, используя разрешение области, а затем зачем использовать указатель и назначить ему объект?

Теги:
pointers
polymorphism
visual-c++

3 ответа

1
Лучший ответ

Допустим, у вас 3 разных автомобиля. И у вас разные механизмы их вождения. Водителю не нужно знать о базовых двигателях, но только протокол о том, как управлять автомобилем, т.е. нажмите эту педаль для ускорения, нажмите эту педаль для торможения и т.д.

Теперь с точки зрения водителя не имеет значения, есть ли его Honda, Ford или Buick. С его точки зрения, это всего лишь автомобиль. Точно так же, если вы пролили, где машины припаркованы, вы называете их сараем. В нем есть автомобили и не беспокоит, что делает каждый из них. Так

std::vector<Car*> v;
v.push_back(new Ferrari());
v.push_back(new Honda());
v.push_back(new Ford());

почему нам нужно использовать ссылку/указатель, когда такую же работу можно сделать, создав объект класса?

Без указателя или ссылки вы не можете создать коллекцию объектов, которые имеют некоторую общность, но различаются в определенном смысле. Это обходит некоторые строгие языки ООП, такие как Java, С# и т.д., Делая все объекты производными от базового класса Object. C++ - это язык с несколькими парадигмами, и программист может принимать такие решения в зависимости от своего проекта. Способ сделать это в C++ - через указатели базового класса. Эта идиома называется полиморфизмом во время выполнения.

for (const auto &this_car : v)
     this_car->drive();

Здесь, независимо от фактических замыкающих, вектор v будет иметь возможность держать машину, до тех пор, как базовый класс car является частью типа. Аналогично, drive будет отличаться для каждого make, но это не обязательно должно быть известно для функции, которая его вызывает.

РЕДАКТИРОВАТЬ:

Благодаря nijansen для указания, что этот пост на самом деле не отвечает на вопрос: почему указатели или ссылки (динамические типы) необходимы для полиморфизма во время выполнения? он только говорит, что они должны были его использовать, но не объясняет, почему мы не можем использовать обычные (статические типы) переменные.

C++ разработан таким образом, что тип объекта может или не может быть полностью известен во время компиляции только с типом в руке. В Circle c; мы знаем, что c имеет тип Circle; тогда как в Shape *p = make_shape(); мы действительно не знаем, к чему указывает объект p; p собственный тип Shape* но его конкретный конкретный тип объекта неизвестен. Все, что мы знаем, это то, что он указывает на какой-то объект, который происходит от Shape. Пожалуйста, не путайте себя с динамическим или автоматическим распределением памяти; это то же самое для автоматических переменных. Eg Shape *p = &c; , Здесь тоже p изолированно компилятор не знает, к какому конкретному типу относится объект, на который указывает p.

Если бы мы написали p как статический (не указательный, не ссылочный) тип Shape p = make_shape(); или Shape p = c; что действительно происходит при разрезе, т.е. p будет иметь конкретный тип Shape и, поскольку он не является указателем, он скопирует (Shape) часть объекта Circle c ему, что в основном нежелательно.

Не зная базового типа, как мы называем нужные конкретные функции типа? C++ предоставляет виртуальные функции для выполнения задания. Вот почему полиморфизм во время выполнения всегда объясняется виртуальными методами в C++; в то время как в таких языках, как Java и С#, все методы являются виртуальными, а все типы объектов - ссылками/указателями. В некотором роде ответ на ваш вопрос заключается в том, что язык разработан таким образом, что для переменных полиса времени выполнения требуются переменные reference/pointer.

  • 0
    Это объясняет полиморфизм, но не этот вопрос: «почему мы должны использовать ссылку / указатель, когда та же самая работа может быть сделана путем создания объекта класса?» возможный дубликат, который я отметил, покрывает это довольно хорошо
  • 0
    @nijansen: я добавил это сейчас. Спасибо!
0

Таким образом, вы можете выполнить некоторую общую процессу для каждого объекта. Например, у вас есть Chicken: Animal class, и у вас есть Cow: Animal class, и у них есть общая функция doSlaughter(), и у вас есть класс SlaughterHouseJob. Когда вы хотите обработать slaughterHouseJob.doSlaughterAnimals() метод, вы можете просто написать этот код:

for(Animal animal:animals){
    animal.doSlaughter(); //It can be chicken or Cow or other animals. Simply one function for all jobs
}
0

Чтобы дать вам общий пример,

Пожалуйста, извините pseduocode.Добавит код Cpp за какое-то время, теперь немного ржавый

Суперкласс

Class Animal
{

}

Подкласс

Class Dog : public Animal
{

}

Class Cat : public Animal
{

}

Другой класс,

class Vet 
{
    void checkAnimal(recieve Animal)
    {

    }          
}

Теперь рассмотрим это использование,

vetObject.checkAnimal(dogObject);
vetObject.checkAnimal(catObject);

Если бы не полиморфизм, ваш Vet Class был бы чем-то вроде этого,

class Vet 
{
    void checkAnimal(recieve Cat)
    {

    }          

    void checkAnimal(recieve Dog)
    {

    }          

     ....  and so on
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню