2016-06-21 4 views
0

Я пытаюсь понять, если моя ошибка связана с проблемой проектирования или ошибкой кода. Мой поиск показал мне вопрос Slicing, но я не вижу в этом проблемы.Poylmorphism, переопределенный метод, используемый в конструкторе - C++

#include <string> 
#include <iostream> 
#include <vector> 

    class BaseA { 
    public: 
     BaseA(const std::string &n) 
      : name(n) 
     {} 
     virtual ~BaseA() 
     {}; 
     virtual void print() const 
     { 
      std::string str(""); 
      str += name; 
      std::cout << str << std::endl; 
     } 

    protected: 
     std::string name; 
    }; 

    class BaseB : public BaseA { 
    public: 
     BaseB(const std::string &n, const std::string &v) 
      : BaseA(n), value(v) 
     { 
      load(); 
     } 
     virtual ~BaseB() 
     {}; 
     virtual void load(){ 
      c = 'B'; 
     } 
     char getC() { 
      return c; 
     } 
     void print() const{ 
      std::string str(""); 
      str += name; 
      str += ' '; 
      str += value; 
      std::cout << str << std::endl; 
     } 
    protected: 
     char c; 
    private: 
     std::string value; 
     int data = 0; 
    }; 

    class BaseC : public BaseB { 
    public: 
     BaseC(const std::string &n, const std::string &v) 
      : BaseB(n, v) 
     { 
     } 
     void load() override{ 
      c = 'C'; 
     } 
    }; 

    int mainTest() 
    { 
     std::vector<BaseB*> vec; 
     vec.push_back(new BaseB("John", "singer")); 
     vec.push_back(new BaseC("Raoul", "wannabe")); 
     for (BaseB *obj : vec) 
     { 
      obj->print(); 
      std::cout << "load class: " << obj->getC() << std::endl; 
     } 
     return(0); 
    }; 

Я бы ожидать, чтобы результат:

John singer 
load class: B 
Raoul wannabe 
load class: C 

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

ответ

3

Это не невозможно, но он может не делать то, что вы хотите.

Напомним, что для BaseC заказ на строительство BaseA, BaseB, BaseC.

В то время как BaseB строится (конструктор, выполняющий), не существует такого объекта, как BaseC, даже если она строится как часть BaseC строительства.

Стандарт поэтому гарантирует, что во время конструктора (и деструктора) BaseB, вызывающий load() приведет к выходу BaseB::load(). Не установлено BaseC::load()

Смежные вопросы