C++ linkage within class - c++

Being new to C++, I have trouble understanding a linkage problem I'm having. The following is the file that's giving me a headache:
#pragma once
#include <string>
#include "finite_automaton.h"
template<typename RL>
class RegularLanguage {
public:
bool empty();
RegularLanguage<RL> minimize();
RegularLanguage<RL> complement();
RegularLanguage<RL> intersectionWith(RegularLanguage<RL> other);
RegularLanguage<RL> unionWith(RegularLanguage<RL> other);
RegularLanguage<RL> concatenate(RegularLanguage<RL> other);
RegularLanguage<RL> kleeneStar();
/*
* Returns a regular expression that describes the language of this automaton.
*/
std::string string();
bool disjoint(RegularLanguage<RL> other) {
return intersectionWith(other).empty();
}
bool containedIn(RegularLanguage<RL> super) {
return intersectionWith(super.complement()).empty();
}
bool contains(RegularLanguage<RL> sub) {
return complement().intersectionWith(sub).empty();
}
bool equals(RegularLanguage<RL> other) {
return contains(other) && containedIn(other);
}
};
When I compile the project, I get the following errors during the linking phase:
undefined reference to `RegularLanguage<FiniteAutomaton>::complement()'
undefined reference to `RegularLanguage<FiniteAutomaton>::intersectionWith(RegularLanguage<FiniteAutomaton>)'
undefined reference to `RegularLanguage<FiniteAutomaton>::empty()'
both for RegularLanguage<RL>::containedIn(..) and RegularLanguage<RL>::contains(..).
What am I doing wrong? I do get some related errors pertaining to the classes that implement this template class, but I left them out so as not to post unnecessarily much code.

So to summarize what you're trying to do, you have a class template:
template<typename RL> class RegularLanguage {...};
with some methods implemented and others only declared, but not implemented. Then you try to derive from this and in the derived class implement those other methods that weren't implemented in RegularLanguage:
class FiniteAutomaton : public RegularLanguage<FiniteAutomaton>
You seem to be conflating two concepts in C++: inheritance (specifically, polymorphism) and templates.
Your assumption was that by inheriting from RegularLanguage you can implement the missing stuff in the derived class. That's not how templates work, but polymorphism does work that way. You need to either:
Fully implement all methods in the class template RegularLanguage, and then derive FiniteAutomaton from that.
Make RegularLanguage an abstract base class -- not a class template -- with (possibly pure) virtual methods, and derive from that. The methods you want to be implemented in FiniteAutomaton can be. Those may or may not be pure. The methods you don't want to implement in the base class should be declared as pure (=0), and then implemented in the derived class.
It sounds to me like what you're really trying to do would be better accomplished with #2, so here's an incomplete example of how to do that:
class RegularLanguage {
public:
virtual RegularLanguage* Clone() = 0; // Creates a copy of this object
virtual RegularLanguage& complement() = 0; // pure virtual must be implemented in derived class
virtual bool containedIn(RegularLanguage& super) // non-pure, does not have to be implemented in derived
{
return intersectionWith(super.complement()).empty();
}
virtual ~RegularLanguage() {}
};
class FiniteAutomaton
:
public RegularLanguage
{
public:
RegularLanguage* Clone()
{
RegularLanguage* clone = new FiniteAutomaton (*this);
return clone;
}
RegularLanguage* complement()
{
RegularLanguage* comp = this->Clone();
comp->SetSomeStuff();
return comp;
}
};
There are a number of details hidden up there that I haven't mentioned. For one, the return type of complement is now a RegularLanguage pointer, rather than a RegularLanguage by-value. This is required1 in order to avoid the so-called Slicing Problem which would break polymorphism.
For another, I have abandoned the use of templates here because as I've implemented this, there is no apparent need for them. However the use of templates and polymorphism are not completely mutually exclusive. The base class could employ templates, and in fact the base class could be a class template and still be an abstract base class. But the derived class must derive from a concrete instantiation of that base class template. Things get somewhat complicated here. Just be careful that you're not seeing everything as a nail and get carried away with that hammer.
For another, I didn't implement a virtual destructor in the base class before (this is fixed now) but you must2. Just remember this: if a class is intended to be derived from, it should have a virtual destructor in virtually every case.
For another, I've added a Clone method to the base class as a pure virtual. This was in response to the suggestion that complement() shouldn't return this instance of the object, but a new instance which is the complement of this instance. In a polymorphic hierarchy, when we make copies of object we almost always need to do so through the base class pointer, so a Clone() type method is usually present in such a design.
1 "This is required [passing by pointer]: Actually, you could return a reference as well. Return a reference if you can, but here we need to return a pointer. (Actually we should be returning smart pointers, but that's a tangent.)
2 "You must [implement a virtual destructor]: Technically, you need to have a virtual destructor if you intend to delete the object through a base class pointer. I have never in my professional career seen an instance where I could not or should not implement a virtual destructor in the base class of a polymorphic hierarchy. It's close to correct to say you should always do this, even if you have no plans to delete through a base class pointer.

You need to declare bool empty() (and others not implemented in the base) as a pure virtual in the base class:
virtual bool empty() = 0;
and then override/implement them in a descendant class like this:
virtual bool empty(){
...
}

There is a series of problems with this code. The most obvious one has been pointed out: you need your functions pure virtual. But that's just the beginning.
When you make your functions pure virtual, you will immediately notice that the code does not compile any more. The tools will tell you that you cannot instantiate an abstract class. The reason is that you return objects of type ReguarLanguage<...> from your functions by value, thereby invoking the Curse of Object Slicing (look it up). The inability to instantiate an abstract class is just manifestation of Object Slicing.
In order to dispel the dreaded curse, you will have to do the Rite of Return by Pointer, and thereby invoke the lesser curse of Manual Memory Management (this is relatively easily defeated with a bit of Smart Pointer Magic these days).
But you are not only returning languages, you are also accepting them as arguments. Here you need a simpler incantation of Passing by Reference, which does not require any manual memory management. It looks like in your case you can implement the intersection and all the other things by using just the public interface of the "other" argument, so this simple change should suffice.
Oh, and don't forget the virtual destructor. Never forget the virtual destructor... only omit it if you know you don't need it, which is, if your class fits the OO paradigm, never.
If you look at your RegularLanguage class template, you may notice that it never use its template parameter. If this is the case, it can be safely de-templatized. No, wait, it does use the parameter — how else could it create e.g. a complement?
To put it simply, if you have a finite automaton that parses a language, the parser of the complement doesn't have to be a finite automaton. It may contain or reference a FA (or something else!) instead. So you may want to have a subclass of RegularLanguage called Complement that will contain a (polymorphic!) reference to another RegularLanguage — without even having to know what kind of parser is hidden inside that one.

Related

Defining interfaces (abstract classes without members) in C++

By an interface (C# terminology) I mean an abstract class with no data members. Thus, such a class only specifies a contract (a set of methods) that sub-classes must implement. My question is: How to implement such a class correctly in modern C++?
The C++ core guidelines [1] encourage the use of abstract class with no data members as interfaces [I.25 and C.121]. Interfaces should normally be composed entirely of public pure virtual functions and a default/empty virtual destructor [from C.121]. Hence I guess it should be declared with the struct keyword, since it only contains public members anyway.
To enable use and deletion of sub-class objects via pointers to the abstract class, the abstract class needs a public default virtual destructor [C.127]. "A polymorphic class should suppress copying" [C.67] by deleting the copy operations (copy assignment operator, copy constructor) to prevent slicing. I assume that this also extends to the move constructor and the move assignment operator, since those can also be used for slicing. For actual cloning, the abstract class may define a virtual clone method. (It's not completely clear how this should be done. Via smart pointers or owner<T*> from the Guidelines Support Library. The method using owner<T> makes no sense to me, since the examples should not compile: the derived function still does not override anything!?).
In C.129, the example uses interfaces with virtual inheritance only. If I understand correctly, it makes no difference if interfaces are derived (perhaps better: "implemented"?) using class Impl : public Interface {...}; or class Impl : public virtual Interface {...};, since they have no data that could be duplicated. The diamond problem (and related problems) don't exist for interfaces (which, I think, is the reason why languages such as C# don't allow/need multiple inheritance for classes). Is the virtual inheritance here done just for clarity? Is it good practice?
In summary, it seems that:
An interface should consist only of public methods. It should declare a public defaulted virtual destructor. It should explicitly delete copy assignment, copy construction, move assignment and move construction. It may define a polymorphic clone method. I should be derived using public virtual.
One more thing that confuses me:
An apparent contradiction: "An abstract class typically doesn't need a constructor" [C.126]. However, if one implements the rule of five by deleting all copy operations (following [C.67]), the class no longer has a default constructor. Hence sub-classes can never be instantiated (since sub-class constructors call base-class constructors) and thus the abstract base-class always needs to declare a default constructor?! Am I misunderstanding something?
Below is an example. Do you agree with this way to define and use an abstract class without members (interface)?
// C++17
/// An interface describing a source of random bits.
// The type `BitVector` could be something like std::vector<bool>.
#include <memory>
struct RandomSource { // `struct` is used for interfaces throughout core guidelines (e.g. C.122)
virtual BitVector get_random_bits(std::size_t num_bits) = 0; // interface is just one method
// rule of 5 (or 6?):
RandomSource() = default; // needed to instantiate sub-classes !?
virtual ~RandomSource() = default; // Needed to delete polymorphic objects (C.127)
// Copy operations deleted to avoid slicing. (C.67)
RandomSource(const RandomSource &) = delete;
RandomSource &operator=(const RandomSource &) = delete;
RandomSource(RandomSource &&) = delete;
RandomSource &operator=(RandomSource &&) = delete;
// To implement copying, would need to implement a virtual clone method:
// Either return a smart pointer to base class in all cases:
virtual std::unique_ptr<RandomSource> clone() = 0;
// or use `owner`, an alias for raw pointer from the Guidelines Support Library (GSL):
// virtual owner<RandomSource*> clone() = 0;
// Since GSL is not in the standard library, I wouldn't use it right now.
};
// Example use (class implementing the interface)
class PRNG : public virtual RandomSource { // virtual inheritance just for clarity?
// ...
BitVector get_random_bits(std::size_t num_bits) override;
// may the subclass ever define copy operations? I guess no.
// implemented clone method:
// owner<PRNG*> clone() override; // for the alternative owner method...
// Problem: multiple identical methods if several interfaces are inherited,
// each of which requires a `clone` method?
//Maybe the std. library should provide an interface
// (e.g. `Clonable`) to unify this requirement?
std::unique_ptr<RandomSource> clone() override;
//
// ... private data members, more methods, etc...
};
[1]: https://github.com/isocpp/CppCoreGuidelines, commit 2c95a33fefae87c2222f7ce49923e7841faca482
You ask a lot of questions, but I'll give it a shot.
By an interface (C# terminology) I mean an abstract class with no data members.
Nothing specifically like a C# interface exists. A C++ abstract base class comes the closest, but there are differences (for example, you will need to define a body for the virtual destructor).
Thus, such a class only specifies a contract (a set of methods) that sub-classes must implement. My question is: How to implement such a class correctly in modern C++?
As a virtual base class.
Example:
class OutputSink
{
public:
~OutputSink() = 0;
// contract:
virtual void put(std::vector<std::byte> const& bytes) = 0;
};
OutputSink::~OutputSink() = default;
Hence I guess it should be declared with the struct keyword, since it only contains public members anyway.
There are multiple conventions for when to use a structure versus a class. The guideline I recommend (hey, you asked for opinions :D) is to use structures when you have no invariants on their data. For a base class, please use the class keyword.
"A polymorphic class should suppress copying"
Mostly true. I have written code where the client code didn't perform copies of the inherited classes, and the code worked just fine (without prohibiting them). The base classes didn't forbid it explicitly, but that was code I was writing in my own hobby project. When working in a team, it is good practice to specifically restrict copying.
As a rule, don't bother with cloning, until you find an actual use case for it in your code. Then, implement cloning with the following signature (example for my class above):
virtual std::unique_ptr<OutputSink> OutputSink::clone() = 0;
If this doesn't work for some reason, use another signature (return a shared_ptr for example). owner<T> is a useful abstraction, but that should be used only in corner cases (when you have a code base that imposes on you the use of raw pointers).
An interface should consist only of public methods. It should declare [...]. It should [...]. It should be derived using public virtual.
Don't try to represent the perfect C# interface in C++. C++ is more flexible than that, and rarely will you need to add a 1-to-1 implementation of a C# concept in C++.
For example, in base classes in C++ I sometimes add public non-virtual function implementations, with virtual implementations:
class OutputSink
{
public:
void put(const ObjWithHeaderAndData& o) // non-virtual
{
put(o.header());
put(o.data());
}
protected:
virtual void put(ObjectHeader const& h) = 0; // specialize in implementations
virtual void put(ObjectData const& d) = 0; // specialize in implementations
};
thus the abstract base-class always needs to declare a default constructor?! Am I misunderstanding something?
Define the rule of 5 as needed. If code doesn't compile because you are missing a default constructor, then add a default constructor (use the guidelines only when they make sense).
Edit: (addressing comment)
as soon as you declare a virtual destructor, you have to declare some constructor for the class to be usable in any way
Not necessarily. It is better (but actually "better" depends on what you agree with your team) to understand the defaults the compiler adds for you and only add construction code when it differs from that. For example, in modern C++ you can initialize members inline, often removing the need for a default constructor completely.
While the majority of the question has been answered, I thought I'd share some thoughts on the default constructor and the virtual inheritance.
The the class must always have a public (Or at least protected) constructor to assure that sub-classes can still call the super-constructor. Even though there is nothing to construct in the base class, this is a necessity of the syntax of C++ and conceptually makes no real difference.
I like Java as an example for interfaces and super-classes. People often wonder why Java separated abstract classes and interfaces into different syntactical types. As you probably already know though, this is due to the diamond inheritance problem, where two super-class both have the same base class and therefore copy data from the base class. Java makes this impossible be forcing data-carrying classes to be classes, not interfaces and forcing sub-classes to only inherit from one class (not interface which doesn't carry data).
We have following situation:
struct A {
int someData;
A(): someData(0) {}
};
struct B : public A {
virtual void modifyData() = 0;
};
struct C : public A {
virtual void alsoModifyData() = 0;
};
struct D : public B, public C {
virtual void modifyData() { someData += 10; }
virtual void alsoModifyData() { someData -= 10; }
};
When modifyData and alsoModifyData are called on an instance of D, they will not modify the same variable as one might expect due to the compiler which will create two copies of someData for classes B and C.
To counter this problem, the concept of virtual inheritance was introduced. This means that the compiler will not just brute-force recursively build up a derived class from the super-classes members but instead see if the virtual super-classes derive from a common ancestor. Very similarly, Java has the concept of an interface, which is not allowed to own data, just functions.
But interfaces can strictly inherit from other interfaces, excluding the diamond problem to begin with. This is where Java of course differs from C++. These C++ "Interfaces" are still allowed to inherit from data-owning classes, whereas this is impossible in java.
The idea of having a "virtual inheritance", which signals that the class should be sub-classed and that data from ancestors is to be merged in case of diamond inheritance makes the necessity (or at least the idiom) of using virtual inheritance on "Interfaces" clear.
I hope this answer was (although more conceptual) helpful to you!

C++14 ignore return type in interface getter but specify it in implementation

I have three classes of objects:
class Foo: has a mesh, and I need to get that mesh;
class Bar: is a Foo, but has some further capabilities which Foo doesn't have;
class Baz: is a Foo, but has another completely independent set of capabilities which neither Foo nor Bar have.
All three classes need to have a way to give me their mesh which, however, can be implemented in many ways, of which I need (at the moment I can't see another way) to use at least 2 different ones, which are MeshTypeA and MeshTypeB.
I would like to have a common interface for different implementations of the same concept (getMesh), however, I can't use auto in a virtual method. I'm lacking the facility to make the code have sense. I would like to have:
class Foo
{
public:
virtual ~Foo() = 0;
virtual auto getMesh() const = 0; // doesn't compile
};
class Bar : public Foo
{
public:
virtual ~Bar() = 0;
virtual auto getMesh() const = 0; // doesn't compile
// other virtual methods
};
class ConcreteFooWhichUsesA : public Foo
{
public:
ConcreteFooWhichUsesA();
~ConcreteFooWhichUsesA();
auto getMesh() const override {return mesh_;};
private:
MeshTypeA mesh_;
};
class ConcreteBarWhichUsesB : public Bar
{
public:
ConcreteBarWhichUsesB();
~ConcreteBarWhichUsesB();
auto getMesh() const override {return mesh_;};
// other implementations of virtual methods
private:
MeshTypeB mesh_;
};
MeshTypeA and MeshTypeB are not exclusive to Foo, Bar, or Baz, which is to say all three could have both types of mesh. However I really don't care for which MeshType I get when I later use it.
Do I need to wrap MeshTypeA and MeshTypeB in my own MeshType? Is it a matter of templating the MeshType? I believe there is a way, however related questions aren't helping or I can't formulate my question in a meaningful enough way.
I have also found this where the author uses a Builder class and decltype, but I don't have such a class. Maybe that would be it? Do I need a MeshLoader sort of class as an indirection level?
If your MeshTypes all have a common (abstract) base class, then you can just return (a pointer or reference to) that in the virtual function defintions, and the derived classes can then return their concrete mesh types, and all will be well. If you have code that can work on any mesh type, it is going to need that abstract base anyways.
If your MeshTypes do not all have a common base class, why even have a getMesh method in Foo at all? Remove it and give each of the concrete classes it's own getMesh method that doesn't override (and has nothing in particular to do with the meshes in any other concrete class).
A function's return type is part of its interface. You can't just change it willy-nilly. More specifically, you cannot have a base class virtual method return one thing while an overridden version returns another. OK, you can, but only if the derived version's return type is convertible to the base class return type (in which case, calling through the base class function will perform said conversion on the overriding method's return type).
C++ is a statically typed language; the compiler must know what an expression evaluates to at compile time. Since polymorphic inheritance is a runtime property (that is, the compiler is not guaranteed to be able to know which override will be called through a base class pointer/reference), you cannot have polymorphic inheritance change compile-time constructs, like the type of a function call expression. If you call a virtual method of a base class instance, the compiler will expect this expression to evaluate to what that base class's method returns.
Remember: the point of polymorphic inheritance is that you can write code that doesn't know about the derived classes and have it still work with them. What you're trying to do violates that.

Is-a relationship without virtual functions c++

I couldn't find examples of is-a relationship without virtual functions. Is a following pattern ok?
class Base {
public:
void doSomethingWithX() {/*implementation here*/}
protected:
~Base(){}
private:
int x_;
};
class Derived : public Base {
//Add some other functionality but inherit doSomethingWithX and its implementaion
public:
void doSomethingWithY();
~Derived(); //And document that nobody should inherit further from this class.
private:
int y_;
};
foo(Base* ptr) {
//Do something via Base interface
}
Derived d;
foo(&d);
Edit: I was asked to clarify what I mean by "is this pattern ok".
Does this kind of inheritance satisfies what is usually needed from is-a relationship? Liskov substitution principle etc.
Is it safe to use Derived objects via pointer to Base? (or I miss some problem here).
I'm asking this because there is often written that base class destructor should be either public and virtual or protected and non-virtual. But I never met real examples of public inheritance without non-virtual functions.
It's okay for what you're doing here; You can pass a pointer to Derived and it can bind to a pointer of Base just fine. It's not possible to say whether it satisfies the Liskov subtitution principle because we do not know the invariants of your classes.
Just recognize that without any virtual functions, you cannot use polymorphism. This goes beyond simply overriding function behavior; you'll never be able to perform a dynamic_cast of a pointer to Base to a pointer to Derived.
Additionally, if nobody should derive from Derived, then mark it final, which is available since C++11
There are two types of polymorphism, both implementable in C++: static and dynamic. The latter is what you get with virtual functions and pointers to base classes, in which the behaviour is specialized depending on the real type of object pointed to.
The former can be achieved by writing a template, in which your template type is assumed to have certain interfaces. The compiler will then enforce that when instantiating the template, at compile time. You can provide additional enforcement using SFINAE and/or static_asserts to ensure the type used "is a" or rather conforms to the templated interface used by your code. Note there is not really a straightforward way of defining this interface as with a base interface class, aside from the aforementioned methods.
Note that static polymorphism is what you get at compile time. No dynamically chosen types at runtime. You'll need some form of base class for that.

Inheritance with incomplete base class

I've a question regarding a concept. First, I'm a mechanical engineer and not a programmer, thus I have some C++ knowledge but not much experience. I use the finite element method (FEM) to solve partial differential equations.
I have a base class Solver and two child linSolver, for linear FEM, and nlinSolver for non-linear FEM. The members and methods that both children share are in the base class. The base class members are all protected. Thus using inheritance makes the child classes "easy to use", like there weren't any inheritance or other boundaries. The base class itself, Solver, is incomplete, meaning only the children are of any use to me.
The concept works actually pretty good - but I think that having an unusable class is a bad design. In addition I read that protected inheritance is not preferred and should be avoided if possible. I think the last point don't really apply to my specific use, since I will never use it allow and any attempt to do so will fail (since it is incomplete).
The questions are:
Is it common to use inheritance to reduce double code even if the base class will be unusable?
What are alternatives or better solutions to such a problem?
Is protected inheritance really bad?
Thank you for your time.
Dnaiel
Having "unusable" base classes is actually very common. You can have the base class to define a common interface usable by the classes that inherits the base-class. And if you declare those interface-functions virtual you can use e.g. references or pointers to the base-class and the correct function in the inherited class object will be called.
Like this:
class Base
{
public:
virtual ~Base() {}
virtual void someFunction() = 0; // Declares an abstract function
};
class ChildA : public Base
{
public:
void someFunction() { /* implementation here */ }
};
class ChildB : public Base
{
public:
void someFunction() { /* other implementation here */ }
};
With the above classes, you can do
Base* ptr1 = new ChildA;
Base* ptr2 = new ChildB;
ptr1->someFunction(); // Calls `ChildA::someFunction`
ptr2->someFunction(); // Calls `ChildB::someFunction`
However this will not work:
Base baseObject; // Compilation error! Base class is "unusable" by itself
While the (working) example above is simple, think about what you could do when passing the pointers to a function. Instead of having two overloaded functions each taking the actual class, you can have a single function which takes a pointer to the base class, and the compiler and runtime-system will make sure that the correct (virtual) functions are called:
void aGlobalFunction(Base* ptr)
{
// Will call either `ChildA::someFunction` or `ChildB::someFunction`
// depending on which pointer is passed as argument
ptr->someFunction();
}
...
aGlobalFunction(ptr1);
aGlobalFunction(ptr2);
Even though the base-class is "unusable" directly, it still provides some functionality that is part of the core of how C++ can be (and is) used.
Of course, the base class doesn't have to be all interface, it can contain other common (protected) helper or utility functions that can be used from all classes that inherits the base class. Remember that inheritance is a "is-a" relationship between classes. If you have two different classes that both "is-a" something, then using inheritance is probably a very good solution.
You should check the concept of Abstract class.
It's designed to provide base class that cannot be instantiated.
To do so you provide at least one method in the base class like this
virtual void f()=0;
Each child have to override the f function (or any pure virtual function from the base class) in order to be instantiable.
Don't think of the BaseClass as a class in its own right, but as an interface contract and some implementation help. Therefore, it should be abstract, if neccessary by declaring the dtor pure virtual but providing an implementation anyway. Some OO purists may frown upon any non-private element, but purity is not a good target.

How to avoid clone() boilerplate code for polymorphic objects in c++

If I want to clone a polymorphic object in C++ (i.e. an instance of a class A which is derived from some other class B), the easiest way seems to give B a virtual clone member function, that has to be overridden by A and looks like this
A* clone(){
return new A(*this);
}
My problem is, that I find this unnecessary boilerplate code, as this is almost always needed, if one wants to use run-time polymorphic features of C++. How can it be circumvented?
Thanks
Why I need this:
My use case can be abstracted to the following example:
I have a class Integral, which evaluates the integral of some function. Do do this, they have a member which is a pointer to the class MathFunction. This abstract class contains a pure virtual function evaluate which takes one argument. I I wanted to implement the power function I would create a class PowFunction : class MathFunction. This class would have a member exponent and the function evaluate would look like this:
double evaluate(x){
return pow(x,exponent);
}
As stated the member MathFunction of class Integral has to be polymorhpic, which requires it to be a pointer. To answer the questions of the commenters with another question. Why wouldn't I want to be able to make copies of MathFunction objects?
I really want the Integral to "own" its MathFunction, meaning, that it can alter the parameters (like exponent) without changing the MathFunction of any other Integral object. This means every Integral needs to have its own copy. This requires a clone() function for MathFunctions, doesn't it?
One alternative i thought of: If several Integral objects can share the same MathFunction via a pointer to the same address, I could create copies of Integral objects without the need to copy the MathFunction. But in this case I would have to make all the properties const or somehow readonly, which is not very elegant either. Also, which Integral object should handle delete the MathFunction object?
Why you need this:
Are you seriously saying, that as soon as you work with polymorphic objects you don't ever need a copy operation? What makes polymorphic object different from other objects in this respect?
Using this argumentation, you could also throw the copy constructor and copy assignment operator out of the C++ standard!
Reduce the need to clone polymorphic objects. Really, I rarely find the need for this in my own code, and the comments on the question suggest that I'm hardly alone in the opinion that if you find yourself cloning everything, you're probably designing it wrong.
Of course, never to be unhelpful, you could indeed use the Curiously Recurring Template Pattern.
template<typename T> struct Clone {
virtual T* clone() { return new T(static_cast<const T&>(*this)); }
};
I handled this issue with a macro... it's ugly, but it works to avoid inconsistencies.
/** An interface that can be inherited by any class that wants to provide a Clone()
* method that will return a copy of itself.
*/
class ICloneable
{
public:
ICloneable() {}
virtual ~ICloneable() {}
virtual ICloneable * Clone() const = 0;
};
#define DECLARE_STANDARD_CLONE_METHOD(class_name) virtual ICloneable * Clone() const {new class_name(*this);}
[...]
public MyCloneableClass : public ICloneable
{
public:
MyCloneableClass() {}
DECLARE_STANDARD_CLONE_METHOD(MyCloneableClass);
};