Invalid std :: vector type link initialization

This is mistake:

DummyService.hpp: 35: error: invalid return type of covariant type for 'virtual std :: vector <ResourceBean *, std :: allocator <ResourceBean * → & DummyService :: list (const std :: string &)'

class Bean { public: typedef std::string Path; virtual ~Bean() {}; virtual const Path& getPath() = 0; virtual const std::string& getName() = 0; protected: Bean(); }; class ResourceBean: public Bean { public: ResourceBean(const Path& path, const std::string& contents) : _path(path), _contents(contents) { } virtual ~ResourceBean() { } virtual const Path& getPath(); virtual void setPath(const Path& path); virtual const std::string& getName(); virtual void setName(const std::string& name); private: Path _path; std::string _name; }; 

The above Bean classes are data representations, and they are used by two different layers. One layer uses the Bean interface to access getters for data. Access to the ResourceBean provided by data access classes (DAOs), which take data from the database (for example) and populate the ResourceBean .

One of the responsibilities of a DAO is to list resources defined in a specific way:

 class Service { protected: /* * Service object must not be instantiated (derived classes must be instantiated instead). Service is an interface for the generic Service. */ Service(); public: virtual std::vector<Bean*>& list(const Bean::Path& path) = 0; virtual ~Service(); }; class DummyService: public Service { public: DummyService(); ~DummyService(); virtual std::vector<ResourceBean*>& list(const ResourceBean::Path& path); }; 

I think the problem is that in std::vector<ResourceBean*> compiler does not understand that Bean actually the base class of ResourceBean .

Any suggestions? I read some similar topics, but some of the solutions did not work in my case. Please indicate if I missed something. Thank you in advance.

+4
source share
1 answer

std::vector<Bean*> and std::vector<ResourceBean*> are two completely different types that cannot be converted to each other. You simply cannot do this in C ++ and must adhere to the pointer vector to the base class. In addition, because of this, if this virtual function does not do what you think it does, different types of returned data make it a different method signature, so instead of overloading the method, you introduce a new virtual method. In addition, there is no need to create a constructor that is protected for an abstract class ( Service ), because you cannot create an instance of an abstract class in any case. I would write it something like this:

 #include <string> #include <vector> #include <iostream> class Bean { public: typedef std::string Path; Bean() {} virtual ~Bean() {} virtual void say() const { std::cout << "I am a bean!\n"; } }; class ResourceBean : public Bean { public: ResourceBean() {} virtual ~ResourceBean() {} virtual void say() const { std::cout << "I am a resource bean!\n"; } }; class Service { public: Service() {} virtual ~Service() {} virtual std::vector<Bean*>& list(const Bean::Path &path) = 0; }; class DummyService: public Service { public: DummyService() { for (int i = 0; i < 5; ++i) beans_.push_back(new ResourceBean()); } virtual ~DummyService() {} virtual std::vector<Bean *>& list(const Bean::Path &path) { return beans_; } private: std::vector<Bean*> beans_; }; int main() { DummyService s; std::vector<Bean *>& l = s.list("some path"); for (std::vector<Bean *>::iterator it = l.begin(), eit = l.end(); it != eit; ++it) { Bean *bean = *it; bean->say(); } } 
+6
source

All Articles