0

I have to create the instance of class which inherits from abstract class. My code is really simple. It should create the instance of object class based on abstract class. The abstract class is template class aswell. Then I need to put this object into storage class which holds pointer to the object. Thats all. This task is some kind of homework.

Is that even possible to create the instance of class based on abstract class?

If yes - what I am doing wrong? If no - how can I make it similar?

#include <iostream> #include <string> #include <memory> // using namespace std; template<typename type1, typename type2, typename type3> class INTERFACE { protected: type1 x; type2 y; type3 name; public: virtual type1 setX() = 0; virtual type2 setY() = 0; }; class child : public INTERFACE<int, float, std::string> { public: child(std::string z) { this->name = z; } int setX(int x) { this->x = x; } float setY(float y) { this->y = y; } }; class storage { private: std::shared_ptr<child> childPTR; public: void setPTR(const std::shared_ptr<child> & pointer) { this->childPTR = pointer; } }; int main(){ std::shared_ptr<child> newChild(new child("xxx")); storage testStorage; testStorage.setPTR(newChild); return 0; } 

Compiling Errors:

templates.cpp: In function ‘int main()’: templates.cpp:44:52: error: invalid new-expression of abstract class type ‘child’ std::shared_ptr<child> newChild(new child("xxx")); ^ templates.cpp:18:7: note: because the following virtual functions are pure within ‘child’: class child : public INTERFACE<int, float, std::string> { ^ templates.cpp:14:23: note: type1 INTERFACE<type1, type2, type3>::setX() [with type1 = int; type2 = float; type3 = std::__cxx11::basic_string<char>] virtual type1 setX() = 0; ^ templates.cpp:15:23: note: type2 INTERFACE<type1, type2, type3>::setY() [with type1 = int; type2 = float; type3 = std::__cxx11::basic_string<char>] virtual type2 setY() = 0; 
11
  • 4
    Use the override specifier. You'll find it illuminating. In particular, () and (int x) do not declare the same parameter list. Commented Jan 22, 2018 at 22:54
  • Also, what's with the title? Commented Jan 22, 2018 at 22:56
  • Sorry about that. Missclick. It should be: Instance of class which inherits from abstract class Commented Jan 22, 2018 at 22:59
  • 2
    You are trying to do too many new things at once. When you attempt to implement new functionalities, tackle them separately, and do not combine them until they work perfectly. Commented Jan 22, 2018 at 23:01
  • Then edit your post and correct the title to what it should be. Commented Jan 22, 2018 at 23:03

2 Answers 2

1

Ok so I'll go over the errors in your code in an order they would execute from the start of main function.

  1. To initialize shared_ptr you should use a dedicated function make_shared. It's always better to not use new if possible and leave the memory handling to classes written for that purpose (such as shared_ptr you are using).
  2. From your question I assume that you wanted to create a child object and save it as ITERFACE. Saving derived classes as their base class reference/pointer is valid.
  3. It would be better to use unique_ptr instead of shared_ptr inside storage class. The name of the class says, that it stores the data, therefore owns it.
  4. Since storage should have it's data saved as unique_ptr, newChild should also be a unique_ptr and then just swap the ownership with the storage
  5. You can't just assign any smart pointer such as shared_ptr. They are responsible for memory they hold and you need to call dedicated functions such as get or swap to manipulate the data they hold.
  6. In the INTERFACE you have your 2 virtual set methods of type type2 setX(). One would expect for them to take as an argument the value they should set given attribute to. The = 0 you used there, means that the method is not implemented and that the inheriting classes should implement it. This right because as the name INTERFACE says, it's only an interface, showing publicly what can be done with class inheriting it, and not actually having any functionality.
  7. Set functions in your child class are missing the override keyword, which tells the compiler that these methods should override functions in base class. Since you have the base classe's implementations wrong, it didn't tell you anything.

I hope i went over all of the issues. If I find anything else or someone else mentions anything I'll add it to the list. And here is an example with all the issues fixed:

#include <iostream> #include <string> #include <memory> template<typename Type1, typename Type2, typename Type3> class Interface { protected: Type1 x; Type2 y; Type3 name; public: // setters with proper signature now virtual void setX(Type1) = 0; virtual void setY(Type2) = 0; }; class Child: public Interface<int, float, std::string> { public: Child(const std::string& z) { name = z; }; void setX(int val) override { x = val; } void setY(float val) override { y = val; } }; class Storage { // private keyword not needed // you also need to specify template arguments of the interface here std::unique_ptr<Interface<int, float, std::string>> _interface; // convention of prefixing private members with _ public: void setPointer(std::unique_ptr<Interface<int, float, std::string>>&& pointer) { // transfers ownership of that memory to _interface _interface = std::move(pointer); } }; int main() { // make_unique creates an instance of child, passing it's arguments // to child's constructor and saves it inside an interface pointer std::unique_ptr<Interface<int, float, std::string>> newChild = std::make_unique<Child>("xxx"); Storage testStorage; // here you must move the ownership to the setPointer function testStorage.setPointer(std::move(newChild)); return 0; } 

I've also refactored your code a bit to follow conventions I like to use in my code. Hope I have gone over all the issues and if you have any other questions, feel free to ask.

P.S.: I don't have an access to a C++ compiler right now so hopefully my provided code will compile without problems.

Sign up to request clarification or add additional context in comments.

1 Comment

Now I am getting a lot of errors. One of them is: error: cannot convert ‘std::_MakeUniq<child>::__single_object {aka std::unique_ptr<child>}’ to ‘int’ in initialization std::unique_ptr<INTERFACE> p = std::make_unique<child>("xxx"); Should I create new post?
0

You have two main issues:

  1. The arguments in interfaces are missing.
  2. In your derived class you must return values for "setX() and Y", however I wouldn't since the name implies it only "sets", is not a getter.

    public: virtual auto setX(type1 x) ->decltype(x) = 0; virtual auto setY(type2 y) ->decltype(y) = 0; 

    ...

     int setX(int x) { this->x = x; return x; } float setY(float y) { this->y = y; return y; } 

2 Comments

BTW, you only need the this-> notation if the parameter name is the same as the member name. IMHO, change the parameter name to remove the this-> notation.
Yes, agree with you. Just left it there to resemble his code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.