I am trying to make a factory method, but it is currently throwing an error:
core\loaders\loader.cpp:11:12: error: cannot convert 'Jpeg' to 'Loader*' in assignment
15 | loader = Jpeg(path);
| ^~~~~~~~~~
| |
| Jpeg
I would like to return a class that is derived from Loader
, in this case that would be Jpeg
. As seen in the code below it does extend the Loader
class, and what I have read is that you can use a pointer to the base class, set it, then return it, so I have tried doing that without success. How can I get my factory to return Jpeg
(and eventually a Png
class).
Here is my Loader header and source:
// 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;
}
The Jpeg
class then extends the Loader
class:
class Jpeg : public Loader {
protected:
char* path;
public:
Jpeg(char* path) {
this->path = path;
}
};
The error is self explanatory - type of loader
is Loader *
which is pointer to Loader
type. You can only assign an address to a pointer. Jpeg(path)
will create an object of type class Jpeg
and not a pointer of type class Jpeg
. Looking at your use case, you need to allocate object of type Jpeg
dynamically:
loader = new Jpeg(path);
Once you are done with the Jpeg
object, make sure to dealloate the memory using delete
operator.
C++
discourages the use of bare pointers, instead, you should prefer to use the smart pointers. A smart pointer is an abstract data type that simulates a pointer while providing added features, such as automatic memory management. In your code, you can use them like this -
std::shared_ptr<Loader> loader;
if (pathStr == "jpeg" || pathStr == "jpg") {
loader = std::make_shared<Jpeg>(path);
}
You need to change the return type of Loader::get()
function as well -
std::shared_ptr<Loader> Loader::get(char* path) {
^^^^^^^^^^^^^^^^^^^^^^^
and need to do changes in function declaration as well in the similar way.
Also, when coding in C++
, avoid using the char *
type and prefer to use string
type. For e.g. -
std::string s{"test.jpeg"};
std::shared_ptr<Loader> x = Loader::get(s);
In Loader::get()
, change the parameter type to std::string &
(std::string
reference) :
std::shared_ptr<Loader> Loader::get(std::string & path) {
^^^^^^^^^^^^^
Need to do changes in class Jpeg
also:
class Jpeg : public Loader {
protected:
std::string path;
public:
Jpeg(std::string & path) {
this->path = path;
}
};