我有一个名为SavableFile的父类,还有两个从SaveA继承的类SaveBSavableFile

它们的定义如下:

class SavableFile {
    SavableFile(std::string _filename) : p_filename(_filename){}
    virtual void write() = 0;
protected:
    std::string p_filename;
}

class SaveA : public SavableFile {
   SaveA(std::string _filename) : SavableFile(_filename) {}
   void write() {
        std::cout << "A" << std::endl;
   }
}

class SaveB : public SavableFile {
   SaveB(std::string _filename) : SavableFile(_filename) {}
   void write() {
        std::cout << "B" << std::endl;
   }
}


我的问题是:是否可以创建一个SavableFile并使用文件名的扩展名将此savableFile转换为saveA或saveB?就像是

 SavableFile(std::string _filename) : p_filename(_filename){
     std::string ext = GetExtension(_filename);
     //this is purely fictionnal, it's only in order to give an idea, i'm not sure if there is a way to do that, that's why i'm asking
     if (ext.lower() == "a"){
          *this = dynamic_cast<SaveA>(*this);
     }
     else {
          *this = dynamic_cast<SaveB>(*this);
     }
}


这样我就可以做这样的事情:

int main(int argc, char* argv[]){
    SavableFile svA("foo.a");
    //Here, SavableFile has been changed into SaveA class because of the constructor of SavableFile
    svA->write();
    //Here should be writed "A"
    SavableFile svB("bar.b");
    svB->write();
    //Here should be writed "B"
}


我总是可以在主体中进行测试,以检查是否必须创建SaveA或SaveB类,但是我认为这不是解决问题的好方法。但是我找不到做到这一点的方法,也没有找到好的措辞来在某处寻求帮助...
可能吗?
非常感谢!

最佳答案

不可以,您不能将现有对象转换为其他类型。

另一种方法是named constructor pattern

class SavableFile {
  public:
    static SavableFile *create(std::string _filename); // named constructor
    virtual void write() = 0;
  protected:
    SavableFile(std::string _filename) : p_filename(_filename){} // actual constructor now protected
    std::string p_filename;
};

SavableFile *SavableFile::create(std::string _filename) {
     std::string ext = GetExtension(_filename);
     if (ext.lower() == "a"){
          return new SaveA(_filename);
     }
     else {
          return new SaveB(_filename);
     }
}


这确实具有始终返回动态分配的指针的缺点。为了解决这个问题,您可以添加另一层抽象:SavableFile将包含一个private FileSaver *p_filesaver,其中FileSaver是仅包含virtual void write()函数的接口。

关于c++ - 在执行期间将父类转换为子类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56847894/

10-10 19:58