C++: Interface enforcing definition of copy-constr - c++

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.

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.

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);
}

Something in your project uses the IResource abstract class and somehow I doubt that it requires that the objects it uses contain particular constructors.
Something else creates IResource objects (possibly lots of things) and to do that it must use a constructor. The concrete classes that get created must implement the necessary constructors or the code will not compile.
So the answer to your question is that you enforce the presence of the constructors by using those constructors in some other code to create objects. Keep in mind, if the constructors aren't being used anywhere, they aren't necessary.

you can push all requirements to the resource implementations like so:
class t_resource_interface {
protected:
virtual ~t_resource_interface();
public:
virtual t_serialization* serializeResource() = 0;
virtual t_thing* cloneResource() = 0;
};
/* type disambiguators */
typedef enum t_load_from_url { LoadFromURL = 0 } t_load_from_url;
typedef enum t_load_from_memory { LoadFromMemory = 0 } t_load_from_memory;
typedef enum t_copy_constructor { CopyConstructor = 0 } t_copy_constructor;
template < typename TResourceImplementation >
class t_resource : public t_resource_interface {
public:
/* copy ctor should generally be avoided due to the expense. introduce a parameter for those cases where it's really needed and disable the standard copy ctor */
t_resource(const t_copy_constructor& copyCtor, const t_resource& other) : t_resource_interface(), d_implementation(TResourceImplementation::CopyConstructor(other.d_implementation)) {
MONUnusedParameter(copyCtor);
}
t_resource(const t_load_from_url& fromFile, const t_url& url) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromURL(url)) {
MONUnusedParameter(fromFile);
}
t_resource(const t_load_from_memory& fromMemory, const t_serialization& serialization) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromMemory(serialization)) {
MONUnusedParameter(fromMemory);
}
virtual ~t_resource() {
}
public:
/* t_resource_interface requirements. implementation forwarded to TResourceImplementation */
virtual t_serialization* serializeResource() {
return this->d_implementation->serializeResource();
}
virtual t_thing* cloneResource() {
return this->d_implementation->cloneResource();
}
private:
/* assuming you will end up needing dynamic allocation/polymorphism along the way... */
t_auto_pointer<TResourceImplementation> d_implementation;
private:
/* prohibited */
t_resource(const t_resource&);
t_resource& operator=(const t_resource&);
};
class t_image_resource_implementation : public t_resource_interface {
private:
static t_image_resource_implementation* ValidationCheck(const t_image_resource_implementation* const arg) {
assert(arg && "allocation or argument error");
if (0 == arg) {
return 0;
}
else if (0 == arg->isValid()) {
delete res;
return 0;
}
else {
return arg;
}
}
public:
static t_image_resource_implementation* CopyConstructor(const t_image_resource_implementation* const other) {
return ValidationCheck(new t_image_resource_implementation(other, ...));
}
static t_image_resource_implementation* LoadFromURL(const t_url& url) {
/* assuming t_image_at_url_resource_implementation exists */
return ValidationCheck(new t_image_at_url_resource_implementation(url, ...));
}
static t_image_resource_implementation* LoadFromMemory(const t_serialization& serialization) {
assert(serialization);
if (0 == serialization) {
return 0;
}
else {
return ValidationCheck(new t_image_resource_implementation(serialization, ...));
}
}
/* some physical ctors and the rest of the implementation... */
public:
/* t_resource_interface requirements */
virtual t_serialization* serializeResource() {
return this->createSerialization();
}
virtual t_thing* cloneResource() {
return this->clone();
}
};
typedef t_resource<t_image_resource_implementation> t_image_resource;
t_error_code ConvertImageToGrayscale(const t_url& sourceUrl, const t_url& destinationUrl) {
t_image_resource imageResource(LoadFromURL, sourceUrl);
/* ... */
}

Related

OOP - Store objects and serve interfaces

I'm currently working on a C++ project, I'm dealing with a home-made class CSound and handling its instances with a CSoundEngine, which allow myself to create a CSound (stored in my CSoundEngine) and return a pointer to it.
The fact is that I would like, for design purposes, to return a pointer to an interface. It is possible to store a real object in a vector for example, and serve it via an interface in C++ (or Java) ?
If the answer is yes, is it possible to store a vector a generic object which can be extended and return a specific interface depending on the child class ?
Thanks !
So, if I understand you correctly, you have something like:
class CSound {
// Whatever
};
class CSoundEngine {
// A lot of stuff
CSound* createSound(/* ... */);
};
And you don't want CSound be returned, but an interface, ALTHOUGH it is internally stored in a vector with it's specific type?
Well the first problem - Interface - is easy to solve:
Create your interfaces and derive from them.
class ISound {
public:
ISound(const ISound&) = delete;
ISound(ISound&&) = delete;
ISound& operator =(const ISound&) = delete;
ISound& operator =(ISound&&) = delete;
virtual ~ISound() = default;
// Your ISound public API here as pure virtual methods, e.g.:
virtual const std::string name() const = 0;
protected:
ISound() = default;
};
class ILoopable {
public:
ILoopable(const ILoopable&) = delete;
ILoopable(ILoopable&&) = delete;
ILoopable& operator =(const ILoopable&) = delete;
ILoopable& operator =(ILoopable&&) = delete;
virtual ~ILoopable() = default;
// Your ILoopable public API here as pure virtual methods, e.g.:
virtual const bool isLoopingActive() const = 0;
virtual bool setLoopingActive(bool) = 0;
protected:
ILoopable() = default;
};
class CDefaultSound
: public ISound {
public:
CDefaultSound () = default;
// ISound implementation
inline const std::string name() const { return mName; }
private:
std::string mName;
};
class CLoopableSound
: public ISound,
public ILoopable {
public:
CLoopableSound()
: ISound(),
ILoopable(),
mLoopingActive(true),
mName("")
{
}
// ISound implementation
inline const std::string name() const { return (mName + "(Loopable)"); }
// ILoopable implementation
inline const bool isLoopingActive() const { return mLoopingActive; }
inline bool setLoopingActive(bool active) { mLoopingActive = active; }
private:
bool mLoopingActive;
std::string mName;
};
int main()
{
// Now you can do something like this, for example, using polymorphism
// in your CSoundEngine (see below)...
ISound *pDef = new CDefaultSound();
ISound *pLoopable = new CLoopableSound();
}
If you want to use only CSound deriving from ISound that's fine, you don't need multiple classes, but then I don't understand the point of using an interface.
Important: Due to the pure virtual interface methods, you cannot instaniate the interface class, so you have to use a pointer or RAII-pointer like shared_ptr or unique_ptr (I'd recommend RAII anyway...)
The second problem - storing specific type in vector - is much harder, since you'd required a single vector foreach permitted type. OR! You store the interface-instances and only use the interface-methods!
class DefaultSoundCreator {
static ISound* createSound(/* Criteria */) { ... }
};
template <typename TSoundCreator>
class CSoundEngine {
public:
CSoundEngine()
: mSoundCreator() {
}
std::shared_ptr<ISound> createSound(/* some criteria */);
private:
std::vector<std::shared_ptr<ISound>> mSounds;
};
// cpp
std::shared_ptr<ISound> CSoundEngine::createSound(/* some criteria */) {
// Use criteria to create specific sound classes and store them in the mSOunds vector.
ISound *pSound = TSoundCreator::createSound(/* forward criteria for creation */);
std::shared_ptr<ISound> pSoundPtr = std::shared_ptr<ISound>(pSound);
mSounds.push_back(pSoundPtr);
return pSoundPtr;
}
int main() {
std::unique_ptr<CSoundEngine<DefaultSoundCreator>> pEngine = std::make_shared<CSoundEngine<DefaultSoundCreator>>();
std::shared_ptr<ISound> pSound = pEngine->createSound(/* Criteria */);
}
This way you could rely on the functionality provided by ISound, but by specifying the Creator-class, you could control sound-creation with a generic sound engine.
Now the actual problem of type-erasure using interface base classes: You known you stored a CLoopableSound at index 2 but you can only use ISound-Interfacemethods, due to the sound-engine's method createSound() : std::shared_ptr;
How do you access the ILoopable-behaviour?
And this is the point, where it becomes philosophical... I would recommend reading:
https://akrzemi1.wordpress.com/2013/11/18/type-erasure-part-i/
Type erasure techniques
https://aherrmann.github.io/programming/2014/10/19/type-erasure-with-merged-concepts/
One technique I like to use:
class CLoopableSound
: public ISound {
// All the above declarations and definitions
// AND:
static std::shared_ptr<CLoopableSound> fromISound(const std::shared_ptr<ISound>& other, bool *pSuccess = nullptr) {
std::shared_ptr<CLoopableSound> p = std::static_pointer_cast<CLoopableSound>(other);
if(pSuccess)
*pSuccess = p.operator bool();
return p;
}
};
// Use like
std::shared_ptr<CLoopableSound> pLoopable = CLoopableSound::fromISound(pSoundEngine->getSound(...));
if(pLoopable) {
// Use
}
Finally, you could of course make the fromISound-function a template and use the casts to access only ILoopable instead of CLoopableSound, etc..

Design test with templates and inheritance

I have a question regarding a design in C++.
As you see in the code below there is a design problem. I want to be able to have a TestClass which inherits from zero or more classes derived from ModeBase (ModeOne and ModeTwo in this example). If TestClass inherits from ModeOne, it would have the ability to use MethodeOne(), and it would be a requirement for TestClass to implement MethodOne() which is what I want.
class ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeBase() = default;
};
class ModeOne : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeOne() = default;
virtual void MethodOne() {}
};
class ModeTwo : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeTwo() = default;
virtual void MethodTwo() {}
};
class TestBase
{
//--Methods--------------------------------------------------------------------
public:
TestBase() : currentMode_( nullptr ) {}
virtual ~TestBase() = default;
template <class Mode, class T>
void ChangeMode()
{
if( std::is_base_of<Mode, T>::value )
{
// Class does inherit from Mode so we make sure the current mode
// has changed
currentMode_ = std::make_shared<Mode>();
}
else
{
// Class does not inherit from Mode so we don't do anything
}
}
template <class Mode>
bool CurrentMode()
{
if( std::dynamic_pointer_cast<Mode>(currentMode_) != nullptr )
{
return true;
}
return false;
}
//--Data members---------------------------------------------------------------
private:
std::shared_ptr<ModeBase> currentMode_;
};
class TestOne
: public TestBase
, private ModeOne
, private ModeTwo
{
//--Methods--------------------------------------------------------------------
~TestOne() = default;
void HeartbeatTick()
{
if( CurrentMode<ModeOne>() )
{
MethodOne();
}
else if( CurrentMode<ModeTwo>() )
{
MethodTwo();
}
}
virtual void MethodOne() {}
virtual void MethodTwo() {}
};
class SomeManager
{
~SomeManager() = default;
void ChangeAllMode()
{
for( auto it = vector_.begin(); it != vector_.end(); ++it )
{
// Here is the problem with this implementation. I need to know
// the type of the TestBase derived class (TestOne) to use it as
// a `ChangeMode` method template parameter.
//(*it)->ChangeMode<AIModeFollowLine, SOMETYPE>();
}
};
std::vector<std::shared_ptr<TestBase>> vector_;
};
I already know this is bad design since vector_ will be filled at runtime so I have no way of using ChangeMode like that. It appears that it would be a good solution to use multimethods, wouldn't it ? If so, what would the design look like ?
Multimethods (AKA multiple dispatch) deals with the issue of dispatching a call to a single function based on the runtime type of the parameters involved. This does not appear to be your issue (or have I misunderstood you?), as you have two different method names, implemented on two different types.
Your goal appears to be to select a method implementation based on a runtime type that you have injected into a class. It is not clear whether you are able to dictate the form which that injection takes but if you are then why do you not directly inject the implementation? Then you could use an implicit interface rather than an explicit one. In other words why not inject a functor-like object?
class TestBase
{
public:
typedef std::function<void ()> Ticker;
TestBase(Ticker hbTicker) : ticker{hbTicker} {}
void HeartbeatTick() {
ticker();
}
void setTicker(Ticker hbTicker){
ticker = hbTicker;
}
private:
Ticker ticker;
};
Seems like a lot less complicated to me if that meets your requirements.
If you really do need to implement multiple dispatch you will probably need to implement a visitor pattern on each of the parameters whose runtime type you need to determine. Not sure if that would work for multiple parameters though (I've not tried multiple parameters myself at least). Or you could use RTTI and a case statement or something like that.
I am just being stupid here !
I just have to use a different ChangeMode() method in order to know if TestBase and thus TestOne is of type ModeBase:
template<typename Mode>
bool
IsSame( TestBase* base )
{
return dynamic_cast<Mode*>(base) != nullptr;
};
template <class Mode>
void
ChangeMode()
{
if( isSame<Mode>(this) )
{
// Change the ticker method
}
else
{
}
}

How can I store in a derived class information obtained during initialization of a base class?

I have the situation that, as a side-effect of coming up with data to initialize a base class, a derived class calculates a piece of information that must later be available through its interface. The following gives an idea of the problem, using a boolean as the information wanted:
class base {
public:
base(some_initialization_data);
// ...
};
class derived : public base {
public:
derived()
: base(calc_init_data())
{
}
bool condition_x_occurred() const
{
// How to get at the information obtained
// during the call to calc_init_data()?
}
private:
static some_initialization_data calc_init_data()
{
// This piece of information will later be needed:
const bool condition_x_occurred = /* ... */;
return some_initialization_data(condition_x_occurred);
}
};
The problem with this is that the important piece of information is calculated during the initialization of the base class, before the derived class' own data members are initialized. I must thus not write to the derived class' data elements yet. While I am sure I can get away with a boolean not yet officially created on any platform I have come across in the last 20 years, I would want to avoid invoking undefined behavior.
Note that the information in question has nothing to do at all with the base class, so storing it in the base class is no option. Also, the information can not be stored in a static data member. I have a few ideas about how to refactor the code so that I can do this, but the ones I could come up with all seem quite intrusive for such a small issue. So I wonder if one of you can come up with something simple?
Note: Since we're on an embedded platform, we're stuck with GCC 4.1.2. So strictly C++03 (including TR1), but no C++11.
in C++11, you may do something like:
class derived : public base {
public:
derived() : derived(calc_init_data()) {}
bool condition_x_occurred() const { return my_condition_x_occurred; }
private:
derived(const std::pair<bool, some_initialization_data>& p) :
base(p.second), my_condition_x_occurred(p.first)
{}
static std::pair<bool, some_initialization_data> calc_init_data()
{
// This piece of information will later be needed:
const bool condition_x_occurred = /* ... */;
return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
}
private:
bool my_condition_x_occurred;
};
In C++03, you may change your derived class to something like:
class derived : public base {
public:
static derived make_derived() { return derived(calc_init_data()); }
bool condition_x_occurred() const { return my_condition_x_occurred; }
private:
derived(const std::pair<bool, some_initialization_data>& p) :
base(p.second), my_condition_x_occurred(p.first)
{}
static std::pair<bool, some_initialization_data> calc_init_data()
{
// This piece of information will later be needed:
const bool condition_x_occurred = /* ... */;
return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
}
private:
bool my_condition_x_occurred;
};
If available on your compiler you can use a delegating constructor:
struct derived_init
{
bool data;
some_initialization_data calc()
{
data = true;
return some_initialization_data();
}
};
class derived : public base {
public:
derived()
: derived(derived_init{})
{ }
bool condition_x_occurred() const
{
return init_data.data;
}
private:
derived(derived_init init)
: base(init.calc()), init_data(init)
{ }
derived_init init_data;
};
With C++03 you could use a default argument:
class derived : public base {
public:
derived(derived_init init = derived_init{})
: base(init.calc()), init_data(init)
{
}
private:
derived_init init_data;
};

How to make a member function in an inheritance hierarchy return always the same value?

I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program. For example:
class Base
{
public:
const std::string getName() const;
bool getAttribute1() const;
int getAttribute2() const;
};
Now I want these functions to return the same result all the time. Furthermore, when another class inherits Base this class should have its own set of attributes and any instance of this derived class should have the same attributes. Also the name should be unique for each class.
I want to know a way to make this as transparent and elegant as possible. Sofar I have considered 2 ideas that I can use:
Make some lock system.
That is provide setters for these attributes, but make them throw a runtime exception when they are called more than once.
Make the getters pure virtual.
In this case, the result of the functions would not be stored inside the object itself. This would make it vaguely clear that the result depends on the dynamic type.
Both ideas sound incredibly lousy, so I need your help.
I am new to C++, but I know there are a lot of idioms and patterns to solve general problems like this one. Do you know any?
I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program
Well, then just provide the corresponding values as arguments to a class constructor, and do not expose any setter method on the public interface. This will make sure the values remain constant throughout the life-time of the object.
To protect against possible errors that would alter the value of those data members from member functions of your class (which of course can access the private data), make those data members const. Notice, that this will force you to initialize those members in the constructor's initializer list.
class Base
{
public:
// Forwarding constructor (requires C++11)
Base() : Base("base", true, 42) { }
const std::string getName() const { return _s; }
bool getAttribute1() const { return _a1; }
int getAttribute2() const { return _a2; }
protected:
// Constructor that can be called by derived classes
Base(std::string s, bool a1, int a2)
: _s(s), _a1(a1), _a2(a2) { }
private:
const std::string _s;
const bool _a1;
const bool _a2;
};
Derived classes would then just construct the base subobject with the appropriate arguments:
class Derived : public Base
{
public:
// Provide the values for the constant data members to the base constructor
Derived() : Base("derived", false, 1729) { }
};
This way you would not incur in the overhead of a virtual function call, and you won't have to rewrite similar virtual functions for each of these members in derived classes.
Make them virtual and hard-code the result which the functions should return:
class Base
{
public:
virtual const std::string getName() const { return "BaseName"; }
virtual bool getAttribute1() const { return whatEverAttributeValueYouWant; }
virtual int getAttribute2() const { return attributeValueHere; }
};
class Derived : public Base {
public:
virtual const std::string getName() const { return "DerivedName"; }
virtual bool getAttribute1() const { return whatEverOtherAttributeValueYouWant; }
virtual int getAttribute2() const { return otherAttributeValueHere; }
};
If you want to describe classes rather than objects, use (kind-of) traits:
template<class T> struct AttributeValues;
template<> struct AttributeValues<Base> {
static const std::string name () { return "BaseName"; }
};
template<> struct AttributeValues<Derived> {
static const std::string name () { return "DerivedName"; }
};
//...
auto nameBase = AttributeValues<Base>::name ();
auto nameDerived = AttributeValues<Derived>::name ();

Avoiding dynamic_cast in implementation of virtual functions in derived class

Here is some sample code explaining what I am trying to achieve.
Basically, I have an algorithm that depends on some basic operations available in a class. I have defined those operations in a pure abstract base class. I want to apply that algorithm to a variety of objects that provide those operations by deriving classes for the specific objects.
However, the different derived objects are incompatible with one another as far those operations are concerned. My question is whether I can avoid using RTTI to ensure that for example, bool derived2::identical(const base* other2), asserts(or other exit mechanism) where other2 is not of type derived2.
One alternative would be to template the function algorithm on the specific derived object, but that would mean that it's implementation would have to live in a header file which I don't want to do since 1) Changing the algorithm code for test purposes can cause recompilation of large portions of the code 2) The algorithm's implementation would be exposed in the header instead of living nicely in a source file hidden from the end-user.
Header file
#include <list>
class base
{
public:
virtual float difference(const base*) const = 0;
virtual bool identical(const base*) const = 0;
};
class derived1 : public base
{
public:
float difference(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// process ...
}
else
{
assert(0);
}
return 1;
}
bool identical(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// compare...
}
else
{
assert(0);
}
return true;
}
};
class derived2 : public base
{
public:
float difference(const base* other2) const
{
// process ...
// other2 has to be of type derived2
return 2;
}
bool identical(const base* other2) const
{
// do comparison
// derived1 and derived2 cannot be compared
return true;
}
};
// Declaration
int algorithm(std::list<base*>& members);
Implementation of algorithm Source file
#include "header_file_containing_base"
int algorithm(std::list<base*>& members)
{
// This function only relies on the interface defined in base
// process members;
return 1;
}
Main program
int main()
{
// Create lists of derived1 and derived2
// Run algorithm on these lists
}
You could use double dispatch (http://en.wikipedia.org/wiki/Double_dispatch)
Well, there is one simple thing: store the real type as a member.
An enum, grouping all the types. It'll become cumbersome if you have a lot of them.
A Factory to generate ids (using templates to only generate one id per item)
...
I'll illustrate the factory id:
class IdFactory
{
public:
template <class T>
static size_t GetId(T const&) // argument deduction
{
static size_t const Id = GetIdImpl();
return Id;
}
private:
static size_t GetIdImpl()
{
static size_t Id = 0;
return ++Id;
}
}; // class IdFactory
And you can use it like such:
class Base
{
public:
explicit Base(size_t id): mId(id) {}
size_t const mId; // meaningless to change it afterward...
private:
};
class Derived: public Base
{
public:
explicit Derived(): Base(IdFactory::GetId(*this)) {}
};
Then you can use the mId member for testing. Note that since it's const it can be exposed... otherwise you can create an inline const getter...
float Derived::difference(const Base& rhs)
{
assert( IdFactory::GetId(*this) == rhs.mId );
// ...
}
The cost here is negligible:
GetId is inlined, thus no function call
GetId is lazily initialized, apart for the initialization it amounts to checking that the static member has been initialized: it's typically implemented as a if statement which condition always evaluate to true (apart from the first time).
== is normally fast ;)
The only downside is that you actually need to make sure that you correctly initialize the ids.
There is also a no-storing solution, which involves a virtual function call:
class Other: public Base
{
public:
virtual size_t id() const { return IdFactory::GetId(*this); }
};
It's easier to put in practice because not storing a const member means that you don't have to write the assignment yourself.
You could use a templated function. With templates it is possible to add more classes later without the need to change the original classes, by just adding another template function in another header file. If the only problem is the compile speed - you can implement the template function in a source file apart from the header and use explicit template instanciation.