class Tool {
public:
virtual void mouseUp();
virtual void mouseDown();
virtual ~Tool();
};
class SelectionTool : public Tool {
void mouseDown() override {
std::cout << "SelectionTool icon\n";
}
void mouseUp() override {
std::cout << "Draw a dashed rectangle\n";
}
};
class BrushTool : public Tool {
void mouseDown() override {
std::cout << "BrushTool icon\n";
}
void mouseUp() override {
std::cout << "Draw line\n";
}
};
class Canvas {
Tool _currentTool;
public:
void mouseDown() {
_currentTool.mouseDown();
}
void mouseUp() {
_currentTool.mouseUp();
}
Tool getCurrentTool(){
return this->_currentTool;
}
void setCurrentTool(Tool currentTool) {
this->_currentTool = currentTool;
}
};
int main(int argc, char *argv[]){
auto george = std::make_unique<Canvas>();
george->setCurrentTool(std::make_unique<BrushTool>());
george->mouseDown();
george->mouseUp();
return 0;
}
No suitable user-defined conversion from "std::unique_ptr<Brush, std::default_delete>" to "Tool" exists.
I am following youtube course where that kind of polymorphism is used in Java and I tried to implement it in C but it doesnt work. Whats wrong with that code?
CodePudding user response:
I suspect the polymorphism video you were using didn't use smart pointer types.
You can't just use std::shared_ptr<T> as if it were the underlying type. They have get and set interfaces, but they are not a seamless replacement. If they were, they couldn't do their job!
Using std::unique_ptr adds more conditions that you may not want to deal with right now. I'm just going to use std::shared_ptr here.
If you want shared pointers, I'd suggest making a typedef to the shared pointer type and use that everywhere. You can assign std::shared_ptr<derived> to std::shared_ptr<base> similar to the inheritance rules for raw pointers. Just be sure you have a virtual base destructor, which you do.
#include <iostream>
#include <algorithm>
class Tool {
public:
virtual void mouseUp() {}
virtual void mouseDown() {}
virtual ~Tool() {}
};
typedef std::shared_ptr<Tool> shared_tool_type;
class SelectionTool : public Tool {
void mouseDown() override {
std::cout << "SelectionTool icon\n";
}
void mouseUp() override {
std::cout << "Draw a dashed rectangle\n";
}
};
class BrushTool : public Tool {
void mouseDown() override {
std::cout << "BrushTool icon\n";
}
void mouseUp() override {
std::cout << "Draw line\n";
}
};
class Canvas {
shared_tool_type _currentTool;
public:
void mouseDown() {
_currentTool.get()->mouseDown();
}
void mouseUp() {
_currentTool.get()->mouseUp();
}
std::shared_ptr<Tool> getCurrentTool() {
return this->_currentTool;
}
void setCurrentTool(shared_tool_type currentTool) {
this->_currentTool = currentTool;
}
};
int main(int argc, char* argv[]) {
auto george = std::make_shared<Canvas>();
george->setCurrentTool(std::make_shared<BrushTool>());
george->mouseDown();
george->mouseUp();
return 0;
}