Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Interface enforcing definition of copy-constr

Is there any way for an interface class to enforce a definition of the copy constructor and maybe of also other constructors? In my case, I have an IResource pure abstract class, and I want all classes that implement this interface to define a copy-constr, a constructor for loading from a file, and a constructor for loading from memory.

like image 747
Paul Manta Avatar asked Apr 08 '11 20:04

Paul Manta


2 Answers

In order to construct an object, you need to know the concrete class to use (how would it otherwise know how much memory to allocate, or which virtual table to use, etc..?). As such, the interface is not in play when dealing with constructors, and you can't use interfaces (pure virtuals) to enforce the existence of such a constructor. It's kind of natural when you think about it, virtuals only work when you have a polymorphic object, i.e. after instantiation. Anyone referencing your IResource interface would only ever deal with instantiated objects, and never touch a constructor.

You can enforce these kind of constraints on stuff using templates if you want though. By simply calling the copy constructor from a templated function, the compiler will complain if it encounters a template instantiation using a type which does not have a copy constructor.

like image 53
falstro Avatar answered Nov 11 '22 21:11

falstro


You cannot enforce that and it would not be a right way either. On the contrary, you should prevent the usage of public copy constructors in a polymorphic class hierarchy...

struct IResource {
    virtual IResource* Clone() const = 0;
    virtual ~IResource() {}
};

An implementer of IResource should follow this pattern:

class ConcreteResource : public IResource, public boost::noncopyable { // or equivalent
public:
    virtual ConcreteResource* Clone() const;

    explicit ConcreteResource(std::string const & pString) : mString(pString) {}
private:
    std::string mString;
};

ConcreteResource* ConcreteResource::Clone() const {
    return new ConcreteResource(this->mString);
}
like image 25
Paul Michalik Avatar answered Nov 11 '22 20:11

Paul Michalik