c++ 如何让工厂方法返回一个派生类?

idfiyjo8  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(101)

此问题在此处已有答案

what is return type of new in c++?(2个答案)
10天前关门了。
我正在尝试创建一个工厂方法,但它目前正在抛出一个错误:

core\loaders\loader.cpp:11:12: error: cannot convert 'Jpeg' to 'Loader*' in assignment
   15 |     loader = Jpeg(path);
      |              ^~~~~~~~~~
      |              |
      |              Jpeg

字符串
我想返回一个从Loader派生的类,在本例中是Jpeg。如下面的代码所示,它确实扩展了Loader类,我所读到的是,你可以使用一个指向基类的指针,设置它,然后返回它,所以我试过这样做,但没有成功。我如何让我的工厂返回Jpeg(最终返回一个Png类)?
下面是我的Loader头和源代码:

// loader.h
class Loader {
public:
  static Loader* get(char* path);
};

// loader.cpp
Loader* Loader::get(char* path) {
  string pathStr(path);
  pathStr = pathStr.substr(pathStr.rfind(".") + 1);

  Loader* loader;
  if (pathStr == "jpeg" || pathStr == "jpg") {
    loader = Jpeg(path);
  }

  return loader;
}


然后Jpeg类扩展了Loader类:

class Jpeg : public Loader {
protected:
  char* path;

public:

  Jpeg(char* path) {
    this->path = path;
  }
};

xzv2uavs

xzv2uavs1#

这个错误是不言自明的-loader的类型是Loader *,它是指向Loader类型的指针。你只能给指针分配一个地址。Jpeg(path)将创建一个class Jpeg类型的对象,而不是class Jpeg类型的指针。看看你的用例,你需要动态分配Jpeg类型的对象:

loader = new Jpeg(path);

字符串
完成Jpeg对象后,确保使用delete操作符释放内存。
C++不鼓励使用裸指针,相反,你应该更喜欢使用smart pointers。智能指针是一种抽象数据类型,它模拟指针,同时提供附加功能,如自动内存管理。在你的代码中,你可以这样使用它们-

std::shared_ptr<Loader> loader;
  if (pathStr == "jpeg" || pathStr == "jpg") {
      loader = std::make_shared<Jpeg>(path);
  }


你还需要修改Loader::get()函数的返回类型-

std::shared_ptr<Loader> Loader::get(char* path) {
  ^^^^^^^^^^^^^^^^^^^^^^^


并且需要以类似的方式在函数声明中进行更改。
此外,当以C++编码时,避免使用char *类型,而更喜欢使用string类型。

std::string s{"test.jpeg"};
    std::shared_ptr<Loader> x = Loader::get(s);


Loader::get()中,将参数类型更改为std::string &std::string引用):

std::shared_ptr<Loader> Loader::get(std::string & path) {
                                    ^^^^^^^^^^^^^


需要在class Jpeg中进行更改:

class Jpeg : public Loader {
protected:
    std::string path;

public:

    Jpeg(std::string & path) {
        this->path = path;
    }
};

相关问题