Вызов метода подкласса. Указатель против не указателя

0

У меня есть следующий код:

main.hxx:

#include <iostream>

class Base{
public:
    Base() {}
    ~Base() {}

    virtual void whoAreYou() { std::cout << "I am base!" << std::endl;}
};

class Sub : public Base{
public:
    Sub() {}
    ~Sub() {}

    virtual void whoAreYou() { std::cout << "I am Sub!" << std::endl;}
};

class Factory {

public:
    static Base getBase() { return Base(); }

    static Base* getBasePtr() { return new Base(); }

    static Base getSub() { return Sub(); }

    static Base* getSubPtr() { return new Sub(); }
};

main.cxx

#include "main.hxx"

int main (int argc, char **argv) {

    // Non pointers
    Factory::getBase().whoAreYou();
    Factory::getSub().whoAreYou();

    // Pointers
    Base* basePtr = Factory::getBasePtr();
    Base* subPtr = Factory::getSubPtr();
    basePtr->whoAreYou();
    subPtr->whoAreYou();

    delete basePtr, subPtr;

    return 0;
}

При запуске он печатает следующее:

I am base!
I am base!
I am base!
I am Sub!

Я ожидал "Factory :: getSub(). WhoAreYou();" напечатать "Я Суб!". Это потому, что, когда не используется указатель, он попадает на базу?

Теги:
pointers
inheritance

2 ответа

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

Я ожидал Factory::getSub().whoAreYou(); напечатать "Я Суб!".

Нет, функция возвращает Base, поэтому Base - это то, что вы получаете.

Это потому, что, когда не используется указатель, он попадает на базу?

Да (хотя слово "преобразуется" не "casted" - литье - это явное преобразование, и это преобразование неявно). Это иногда называют "срезанием", так как часть производного класса объекта "разрезается" при копировании.

Кроме того, будьте осторожны:

delete basePtr, subPtr;

только удаляет subPtr. Для каждого из них требуется отдельное выражение. Вам также нужен виртуальный деструктор в Base чтобы безопасно удалить subPtr.

2

Эта строка создает Sub затем вызывает Base конструктор копии по умолчанию для создания экземпляра Base из экземпляра Sub:

static Base getSub() { return Sub(); }

Следовательно, ваш журнал.

Более Generaly Base является Base экземпляром, тогда как Base* представляет собой указатель на Base экземпляра или объект, который наследует Base.

Ещё вопросы

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