Factory method combining static and dynamic polymorphism - c++

I am working with two corresponding class hierarchies, A and B, where I need to create instances of sub-types of B from instances of matching sub-types of A. I can't find a "clean" way to create B objects from A objects because
B objects only have pointers to A objects so a B::factory would not know what kind of B to make as it doesn't know what derived type of A it gets without some sort of ugly dynamic_cast that would be hard to maintain as new sub-types of A and B are added to the library.
B classes depend on template parameters that A classes do not. It's not obvious how a factory method in A could therefore create a B since A classes have virtual inheritance and such a method would need to be templated, which is not possible.
Example classes:
template<typename T>
struct AType {
virtual void apply( const T*, T* ) const = 0;
};
template<typename T>
struct ASubType1 : public AType<T> {
void apply( const T*, T* ) const override;
};
template<typename T>
struct ASubType2 : public AType<T> {
void apply( const T*, T* ) const override;
};
template<typename T, typename U>
class BType {
public:
BType( const AType<T>* A_in ) : A(A_in) {}
virtual std::common_type_t<T,U> compute( const U& ) = 0;
static std::unique<BType> factory( const AType<T>* A_in );
// if A_in has type ASubType1, return std::make_unique<BSubType1<T,U>>
// else if A_in has type ASubType2, return std::make_unique<BSubType2<T,U>>
// else return nullptr
protected:
auto get_A() const { return A; } // So BSubTypes have access
private:
AType<T>* A;
};
template<typename T, typename U>
class BSubType1 : public BType<T,U> {
public:
using BType<T,U>::BType;
std::common_type_t<T,U> compute( const U& ) override;
};
template<typename T, typename U>
class BSubType2 : public BType<T,U> {
public:
using BType<T,U>::BType;
std::common_type_t<T,U> compute( const U& ) override;
};
It seems like there ought to be some sort of clever Vistor-based solution to generating the correct B objects from their corresponding A, however, the only solution besides dynamic_cast
that I have found is to add a method to the A classes that can return an enum corresponding to each A sub-type and have B::factory take this enum as an argument to return the correct sub-type of B. This approach is not particularly satisfying as it requires intrusively changing type information in a base class, where it would be desirable to add new classes to the A and B families without having to touch any existing classes.
Is there a more elegant approach, such as one using visitors, than what I am currently doing?

Related

Inheritance and nested class

I'm trying to implement different versions of a data structure. Suppose it has an interface shown below (it's simplified):
template <typename T>
class Base {
public:
class Iterator {
virtual auto operator*() -> T& = 0;
};
public:
virtual auto Find(const T& value) -> Iterator = 0;
}
Now I want to inherit a class that will implement it:
template <typename T>
class Derived : public Base<T> {
public:
class Iterator {
auto operator*() -> T& override {
/* ... */
}
};
public:
auto Find(const T& value) -> Iterator override {
/* ... */
};
}
Problem is that I need to implement Iterator based on what Derived does, but Find function's signature brakes because of Derived::Iterator (it should be Base::Iterator). Is there a way to do so or do I have to give up on using interface class?
From what I understand, what you are trying to achieve is related to type erasure or maybe static polymorphism. You want Base::Iterator to be a non-abstract generalized type, that can be constructed from any Derived implementation.
This is a dynamic solution that you can optimize based on your needs
template<typename T>
struct Base
{
// This is the interface that needs to be implemented by the derrived classe's iterator
struct IIterator
{
virtual T& Get() = 0;
};
// this is the generalized type that needs to be returned by find()
struct Iterator
{
Iterator(std::unique_ptr<IIterator> impl ):
_impl(std::move(impl))
{
}
T& operator*() { _impl->Get(); }
private:
// You can implement small struct optimization by making a byte array big enough
// to store any of the implementations and avoid dynamic memory
std::unique_ptr<IIterator> _impl;
};
virtual Iterator find() = 0;
};
template<typename T>
struct Derived : public Base<T>
{
// Now in derived we implement our iterator
struct IteratorImpl : Base<T>::IIterator
{
IteratorImpl(T* p) : ptr(p) {}
T& Get() override { return *ptr; }
T* ptr;
};
typename Base<T>::Iterator find() override
{
IteratorImpl result(nullptr);
// After finding we need to construct the generalized type from the implementation
return typename Base<T>::Iterator(std::make_unique<IteratorImpl>( result ));
}
};
Another way to do something like that is by using templates and CRTP to make a static interface. CRTP is a technique that involves passing the derived type information back to the base class using it's template arguments and using that information to define or find an implementation for the Base iterator based on the derived type.

sizeof(*this) and decltype(*this) in derived classes

Suppose there are classes:
struct A {
int a;
virtual size_t GetMemoryUsage() const {
return sizeof(*this);
}
};
struct B : public A {
int b;
};
And there may be deeper inheritance.
What I want is to have a method which will return the number of bytes an object occupies in memory, GetMemoryUsage() in this case. Usually it can be achieved by using sizeof(*this). The problem is (at least AFAIU) that I have to override the method in each derived class and actually copy-paste its body. I don't like duplicated code :)
Am I correct? How can I make sizeof(*this) and decltype(*this) return what I want in subclasses, by calling them only from base class's methods? Is there a more elegant solution?
You do not have to implement GetMemoryUsage for each of your derived classes manually, just leave it as pure virtual. E.g.:
struct A
{
virtual ~A() = default;
virtual size_t GetMemoryUsage() const noexcept = 0;
};
struct B : A
{
int b;
};
When creating objects, however, that function must be implemented. You can do that using a factory function that "decorates" the class with a generic implementation of that pure virtual:
// Can alternatively be defined inside function template create.
template<class T>
struct GetMemoryUsageImpl : T
{
using T::T;
size_t GetMemoryUsage() const noexcept final {
return sizeof(T);
}
};
template<class T, class... Args>
std::unique_ptr<T> create(Args&&... args) {
return std::unique_ptr<T>(new GetMemoryUsageImpl<T>(std::forward<Args>(args)...));
}
Usage:
void f(A& a) {
auto object_size = a.GetMemoryUsage();
}
int main() {
auto b = create<B>();
f(*b);
}
You can also implement a hierarchy of interfaces incrementally easily using this idiom.
This is an insanely generic version of #Maxim's solution.
template<class B0, template<class...>class... Z>
struct TemplateFold {
using type=B0;
};
template<class B0, template<class...>class... Z>
using TemplateFold_t = typename TemplateFold<B0, Z...>::type;
template<class B0, template<class...>class Z0, template<class...>class... Z>
struct TemplateFold<B0, Z0, Z...>
{
using type=Z0< TemplateFold_t<B0, Z...> >;
};
struct ExposeTrivial {
protected:
~ExposeTrivial() {}
};
template<class D, class B0=ExposeTrivial, class...Bases>
struct Expose:B0, Bases... {
// is a template because D isn't a real type when this class is instantiated:
template<class T>
using MakeConcreteType = TemplateFold_t< T, std::conditional_t< std::is_same<B0,ExposeTrivial>{}, T, B0 >::template Implement, Bases::template Implement... >;
template<class...Args>
static std::unique_ptr<D> create( Args&&... args ) {
using ConcreteType = MakeConcreteType<D>;
return std::unique_ptr<D>( new ConcreteType( std::forward<Args>(args)... ) );
}
protected:
~Expose() {}
};
// expose one thing:
struct ExposeMemoryUsage:Expose<ExposeMemoryUsage> {
virtual std::size_t GetMemoryUsage() const noexcept = 0;
template<class B>
struct Implement:B {
using B::B;
std::size_t GetMemoryUsage() const noexcept override final {
return sizeof(*this);
}
};
protected:
~ExposeMemoryUsage() {}
};
// expose a different thing:
struct ExposeAlignment:Expose<ExposeAlignment>{
virtual std::size_t GetAlignment() const noexcept = 0;
template<class B>
struct Implement:B {
using B::B;
std::size_t GetAlignment() const noexcept final override {
return alignof(decltype(*this));
}
};
};
// Expose two things:
struct Bob : Expose<Bob, ExposeMemoryUsage, ExposeAlignment> {
int x;
Bob( int v ): x(v) {}
virtual ~Bob() {}
};
int main() {
std::unique_ptr<Bob> ptr = Bob::create(7);
std::cout << ptr->x << " size:" << ptr->GetMemoryUsage() << " align:" << ptr->GetAlignment() << "\n";
// Bob b; // does not compile
}
simply add more "knows the derived type" static helpers in Exposer to increase functionality.
Live example.
How to use:
Create a Expose type. It should have a pure virtual member, and a template Implement class that (given a class that derives from the Expose type) implements that pure virtual member.
It should inherit from Expose<OwnType> (CRTP) to write the static ::create method for you.
If you want to inherit from additional Expose types (ie, compose two independent Expose interfaces that need to know the concrete type), instead inherit from Expose< YourType, OtherExposeType, AnotherExposeType >. Don't independently inherit from OtherExposeType or AnotherExposeType.
If you do this your Implement template won't be picked up.
I could improve this so that we detect Implement templates in both you and your bases, but that is more metaprogramming than I'm up for right now.

C++ mixing strongly typed base class with CRTP and return value type deduction

I have some conceptual problem in a class hierarchy, where the Base class depends on a fixed scalar type T, but the derived CRTP'ed classes use return value type deduction.
For example, consider the following class hierarchy:
template<typename ... Args> struct VectorBase;
template<typename T>
struct VectorBase<T>
{
virtual T eval(int) const = 0;
auto operator[](int i) {return this->eval(i);}
};
template<typename T, typename Derived>
struct VectorBase<T, Derived> : public VectorBase<T>
{
virtual T eval(int i) const override final { return this->operator[](i); }
auto operator[](int i) const
{
return static_cast<Derived const&>(*this).operator[](i);
}
};
template<typename T>
struct Vector : public VectorBase<T, Vector<T> >
{
//just for code shortness,
//in reality there is a container which returns the corresponding elements
auto operator[](int i) const { return T{}; }
};
template<typename VectorType>
struct SomeTransformation : public VectorBase< /* ... what to write here generically? */ double, SomeTransformation<VectorType> >
{
VectorType const& v;
SomeTransformation(VectorType const& _v) : v(_v) {}
auto operator[](int i) const
{
//do something with vector v and return i-th element, e.g.
return v[i]*0.1;
}
};
DEMO
Now, given a specific vector with value type int, say, one can apply SomeTransformation and get a vector of value type double. Moreover, I can be sure that SomeTransformation derives from VectorBase<double>, so that, for example, I can't falsely assign it to a VectorBase<int>-pointer:
int main()
{
Vector<int> v;
std::cout<<typeid(decltype(v[0])).name()<<std::endl; //prints "i" for int
auto u = SomeTransformation<decltype(v)>(v);
std::cout<<typeid(decltype(u[0])).name()<<std::endl; //prints "d" for double
//works
std::unique_ptr<VectorBase<double> > ud = std::make_unique<SomeTransformation<decltype(v)> >(v);
//gives a compile-time error, which is good
//std::unique_ptr<VectorBase<int> > ui = std::make_unique<SomeTransformation<decltype(v)> >(v);
}
Now for the problem: in the scalar type argument of SomeTransformation, where I wrote /* ... what to write here generically? */, I really would want to write something like
template<typename VectorType>
struct SomeTransformation :
public VectorBase<decltype(std::declval<SomeTransformation<VectorType> >().operator[](0)), SomeTransformation<VectorType> >
{
//...
};
in order to deduce the value type of the transformation automatically and propagate this type down to the base class. However, this doesn't seem to work, which I think is because the base classes are instantiated before the derived class ... so the class of which I want to deduce the type doesn't exists yet.
Is there any way to obtain this behaviour without breaking the inheritance hierarchy?
I figured out a possible alternative by myself and want to bring it up for discussion.
One could for instance add a type parameter T also to the derived class and then use a dummy type in order to instantiate this class once. With this, it is possible to deduce the return type of the so-created class, which is used in a next step to instantiate the class to be really used.
Example:
namespace detail
{
template<typename T, typename VectorType>
struct SomeTransformation :
public VectorBase<T, SomeTransformation<T, VectorType> >
{
//the same as above
};
}
struct DummyType
{
//make any type convertible to DummyType
template<typename T> DummyType(T const&) {}
};
template<typename VectorType>
using SomeTransformationValueType =
decltype(std::declval<detail::SomeTransformation<DummyType, VectorType> >().operator[](0));
template<typename VectorType>
using SomeTransformation =
typename detail::SomeTransformation<SomeTransformationValueType<VectorType>, VectorType>;
DEMO

"dual inheritance" pointer

So an A* pointer can point to any object having a base A, and a B* pointer can point to any object with a base B*. Is there anyway to make a pointer that can only point to objects that have both A and B as a base?
I'd also want it to be something I can store as a class member (perhaps a smart version) without making that class a template class.
Edit:
#KerrekSB asked below what the point of this is. Basically I want to make a number of pure virtual base classes (i.e. interfaces) say printable, flyable, something_else_able etc.
And then I might have a new class which requires in it's constructor requires something which is both printable and flyable. If it was just one or the other, you could store it as a (smart) pointer and let polymorphism take care of the rest, but I'm trying to work out how to do this if the class uses both bases.
Sure, you can use a type trait:
#include <type_traits>
template <typename T, typename A, typename B> struct has_two_bases
: std::integral_constant<bool, std::is_base_of<A, T>:: value &&
std::is_base_of<B, T>:: value> { }
Usage:
static_assert(has_two_bases<T, A, B>::value, "Not a good type");
T * p;
Does something like this fit the bill?
class W {};
class X {};
class Y {};
class Z : public X, public Y {};
template <typename A, typename B>
class DualPointer {
public:
template <typename T>
DualPointer(T *t) : a_ptr_(t), b_ptr_(t) {}
operator A*() { return a_ptr_; }
operator B*() { return b_ptr_; }
private:
A *a_ptr_;
B *b_ptr_;
};
int main() {
Z z;
DualPointer<X, Y> p(&z);
X *x = p;
Y *y = p;
return 0;
}
Or if you're in a C++11 mood:
template <typename... Ts>
class MultiPointer;
template <typename T, typename... Rest>
class MultiPointer<T, Rest...> : public MultiPointer<Rest...> {
public:
template <typename U>
MultiPointer(U *u) : MultiPointer<Rest...>(u), ptr_(u) {};
operator T*() { return ptr_; }
private:
T *ptr_;
};
template <>
class MultiPointer<> {
public:
MultiPointer(void *) {}
};
int main() {
Z z;
MultiPointer<X, Y> p(&z);
X *x = p;
Y *y = p;
return 0;
}
If you're worried about the double storage of pointers, this approach doesn't work. See comments below this answer as to why incorporating Paweł's suggestion of using a union, which works if and only if all the pointers are numerically identical (that is, there's no multiple inheritance or other shenanigans using adjusted this pointers going on), is unsafe and basically useless.
// DON'T USE THIS VARIANT!!!!
template <typename... Ts>
class MultiPointer {
public:
MultiPointer(void *) {}
};
template <typename T, typename... Rest>
class MultiPointer<T, Rest...> {
public:
template <typename U> MultiPointer(U *u) : rest_(u) { ptr_ = u; };
template <typename U> operator U*() const { return rest_; }
operator T*() const { return ptr_; }
private:
union {
T *ptr_;
MultiPointer<Rest...> rest_;
};
};
While you could write a pointer wrapper class (similar to "smart pointers", but not so smart in this case) which only accepts pointers to types derived from A and B, dereferencing them becomes ambiguous. This is a conceptual problem you can't solve with any method.
But you could provide two functions toA() and toB() and/or conversion operators in order to retrieve a pointer to one of the base classes. But as said, you can't (nicely) overload operator* to retrieve the base reference depending on the context (depending on whether an A* or a B* is needed in the context). Same with operator->.
template<typename A, typename B>
class DualPointer {
A *a; // We need two separate pointers because their distance is not known
B *b;
public:
template<typename T>
DualPointer(T* object) :
a(object),
b(object)
{ }
A *toA() const { return a; }
B *toB() const { return b; }
operator A* () const { return a; }
operator B* () const { return b; }
};
Using SFINAE you can also allow a function template which has the actual type as the template parameter, like to<MyBaseA>():
template<typename T>
typename std::enable_if<std::is_same<A, T>::value, T*>::type
to() {
return a;
}
template<typename T>
typename std::enable_if<std::is_same<B, T>::value, T*>::type
to() {
return b;
}
Demonstration of this wrapper class
You can then add such a pointer as a class member as requested in your question:
class MyClass {
DualPointer<MyBaseA, MyBaseB> pointer;
};
and access the pointer like:
pointer.toA()->memberFunctionOfA();
If your types A and B are fixed, then either drop the "template" line and replace A and B accordingly, or add a typedef DualPointer<MyBaseA, MyBaseB> MyAOrB;
Expanding on this, you could say one of the two base classes, say the first, is your "main" base class. That could then be the one the pointer acts like, so the one returned by operator* and operator->. The two operators would then look like:
A * operator-> () const { return a; }
A & operator* () const { return *a; }
Then the call from above can become as easy as
pointer->memberFunctionOfA();
but not simultaneously
pointer->memberFunctionOfB();

Alternative to dynamic casting

Is there an alternative to using dynamic_cast in C++?
For example, in the code below, I want to be able to have Cat objects purr. But only Cat objects and not Dog objects. I know this goes against deriving the class from Mammal since it's not very polymorphic, but I still want to know if I can do this without dynamic_cast.
My class declarations
class Mammal
{
public:
virtual void Speak() const {cout << "Mammals yay!\n";}
};
class Cat: public Mammal
{
public:
void Speak() const{cout << "Meow\n";}
void Purr() const {cout <"rrrrrrrr\n";}
};
class Dog: public Mammal
{
public:
void Speak() const{cout << "Woof!\n";}
};
In Main
int main()
{
Mammal *pMammal;
pMammal = new Cat;
pMammal->Purr(); //How would I call this without having to use dynamic_cast?
return 0;
}
If you know there is a fixed set of implementations, you can create virtual functions that do the casting for you. This can ne cheaper than dynamic_cast.
So:
struct Cat;
struct Mammal {
virtual Cat* AsCat(){ return nullptr; }
};
struct Cat : Mammal {
virtual Cat* AsCat() { return this; }
};
I have done this with template tomfoolery in C++11 so you can even make it look like a cast.
#include <utility>
#include <iostream>
template<typename T>
struct fast_castable_leaf {
virtual T* do_fast_cast(T* unused=nullptr) { return nullptr; }
virtual T const* do_fast_cast(T* unused=nullptr) const { return nullptr; }
virtual ~fast_castable_leaf() {}
};
template<typename Tuple>
struct fast_castable;
template<template<typename...>class Tuple>
struct fast_castable<Tuple<>> {
virtual ~fast_castable() {}
};
template<template<typename...>class Tuple, typename T, typename... Ts>
struct fast_castable<Tuple<T,Ts...>>:
fast_castable_leaf<T>,
fast_castable<Tuple<Ts...>>
{};
template<typename T> struct block_deduction { typedef T type; };
template<typename T> using NoDeduction = typename block_deduction<T>::type;
template<typename T>
T* fast_cast( NoDeduction<fast_castable_leaf<T>>* src ) {
return src->do_fast_cast();
}
template<typename T>
T const* fast_cast( NoDeduction<fast_castable_leaf<T>> const* src ) {
return src->do_fast_cast();
}
template<typename T, typename D>
struct fast_cast_allowed : std::integral_constant<bool,
std::is_base_of<T,D>::value || std::is_same<T,D>::value
> {};
template<typename D, typename B, typename Tuple>
struct implement_fast_cast;
template<typename D, typename B, template<typename...>class Tuple>
struct implement_fast_cast<D,B,Tuple<>> : B {};
template<typename D, typename B, template<typename...>class Tuple, typename T, typename... Ts>
struct implement_fast_cast<D,B,Tuple<T,Ts...>> : implement_fast_cast<D, B, Tuple<Ts...>> {
private:
D* do_cast_work(std::true_type) { return static_cast<D*>(this); }
D const* do_cast_work(std::true_type) const { return static_cast<D const*>(this); }
std::nullptr_t do_cast_work(std::false_type) { return nullptr; }
std::nullptr_t do_cast_work(std::false_type) const { return nullptr; }
public:
T* do_fast_cast( T* unused = nullptr ) override { return do_cast_work( fast_cast_allowed<T,D>() ); }
T const* do_fast_cast( T* unused = nullptr ) const override { return do_cast_work( fast_cast_allowed<T,D>() ); }
};
And an example of the above framework in use:
struct Dog;
struct Cat;
struct Moose;
template<typename...>struct Types {};
typedef Types<Dog, Cat, Moose> Mammal_Types;
// A Mammal can be fast-casted to any of the Mammal_Types:
struct Mammal : fast_castable<Mammal_Types>
{};
// Cat wants to implement any legal fast_casts it can for Mammal in the
// set of Mammal_Types. You can save on overhead by doing Types<Cat> instead
// of Mammal_Types, but this is less error prone:
struct Cat : implement_fast_cast< Cat, Mammal, Mammal_Types >
{};
int main() {
Cat c;
Mammal* m=&c;
// so m is a pointer to a cat, but looks like a mammal. We use
// fast cast in order to turn it back into a Cat:
Cat* c2 = fast_cast<Cat>(m);
// and we test that it fails when we try to turn it into a Dog:
Dog* d2 = fast_cast<Dog>(m);
// This prints out a pointer value for c2, and 0 for d2:
std::cout << c2 << "," << d2 << "\n";
}
Live Example
This can be cleaned up to support a more standard fast_cast<Cat*> instead of a fast_cast<Cat>, as well as fast_cast<Cat&>, then blocking direct access to do_fast_cast by making it private and fast_cast a friend, and allowing for some means to have virtual inheritance in the case that you need it.
But the core of the system is above. You get cast-to-derived at the cost of a single virtual function lookup without having to maintain much of the machinery yourself.
Alternative implementation:
template<class...>struct types{using type=types;};
template<typename T>
struct fast_castable_leaf {
virtual T* do_fast_cast(T* unused=nullptr) { return nullptr; }
virtual T const* do_fast_cast(T* unused=nullptr) const { return nullptr; }
virtual ~fast_castable_leaf() {}
};
template<class Tuple>
struct fast_castable;
template<>
struct fast_castable<types<>> {
virtual ~fast_castable() {}
};
template<class T0, class...Ts>
struct fast_castable<types<T0, Ts...>>:
fast_castable_leaf<T0>,
fast_castable<types<Ts...>>
{};
template<class T> struct block_deduction { typedef T type; };
template<class T> using NoDeduction = typename block_deduction<T>::type;
template<class T>
T* fast_cast( NoDeduction<fast_castable_leaf<T>>* src ) {
return src->do_fast_cast();
}
template<class T>
T const* fast_cast( NoDeduction<fast_castable_leaf<T>> const* src ) {
return src->do_fast_cast();
}
template<class T, class D>
struct fast_cast_allowed : std::integral_constant<bool,
std::is_base_of<T,D>::value || std::is_same<T,D>::value
> {};
template<class Self, class Base, class Types>
struct implement_fast_cast;
template<class Self, class Base>
struct implement_fast_cast<Self,Base,types<>> : Base {
private:
template<class, class, class>
friend struct implement_fast_cast;
Self* do_cast_work(std::true_type) { return static_cast<Self*>(this); }
Self const* do_cast_work(std::true_type) const { return static_cast<Self const*>(this); }
std::nullptr_t do_cast_work(std::false_type) { return nullptr; }
std::nullptr_t do_cast_work(std::false_type) const { return nullptr; }
};
template<class Self, class Base, class T0, class... Ts>
struct implement_fast_cast<Self,Base,types<T0,Ts...>> :
implement_fast_cast<Self, Base, types<Ts...>>
{
public:
T0* do_fast_cast( T0* unused = nullptr ) override { return this->do_cast_work( fast_cast_allowed<T0,Self>() ); }
T0 const* do_fast_cast( T0* unused = nullptr ) const override { return this->do_cast_work( fast_cast_allowed<T0,Self>() ); }
};
struct Dog;
struct Cat;
struct Moose;
typedef types<Dog, Cat, Moose> Mammal_Types;
struct Mammal : fast_castable<Mammal_Types>
{};
struct Cat : implement_fast_cast< Cat, Mammal, Mammal_Types >
{};
int main() {
Cat c;
Mammal* m=&c;
Cat* c2 = fast_cast<Cat>(m);
Dog* d2 = fast_cast<Dog>(m);
std::cout << c2 << "," << d2 << "\n";
}
which might be easier for some compilers to swallow. Live example.
Note that for a long list of types, the above gets unwieldy (at both compile, and possibly run time), because it relies on linear inheritance.
A binary inheritance system would be a bit more complex to program, but would get rid of that problem. In it, you'd split your list of things to inherit from into two lists of equal size and inherit from both. The implement fast cast would have to inherit from Base via a virtual intermediary.
C++ doesn't support sending messages as, e.g., Objective C or Smalltalk do. To call a method you need to have a statically typed handle for an object supporting the method. Whether you need to use a dynamic_cast<Cat*>(pointer) or if you can get away with something else, e.g., a static_cast<Cat*>(pointer) is a separate question.
Since dynamic_cast<...>() is relatively expensive and trying a potentially unbounded number of different classes isn't feasible, it may be preferable to use a visit() method in the base class which is called with a visitor. However, these are just techniques to get hold of a properly typed reference.
You're dealing with a pointer to type Mammal and presumably Mammal does not define Purr(). You absolutely must cast it to a pointer to type Cat in order to access Purr(). You can do this with a C-style cast or a dynamic_cast, and the latter is generally the more proper thing to do in C++. dynamic_cast also has the advantage that you can use it to test, at runtime, whether your Mammal object is a Cat or not, so you can decide whether you can call Purr().
Three variants:
dynamic_cast, which you supposedly already aware of.
static_cast, which is compile-time cast, i.e. a) types are checked for compatibility b) offset between base class and derived class is calculated and taken into account c) there's no runtime check.
reinterpret_cast, which is also compile-time cast, done without any type check and without offset calculation. Use with caution - this cast might cause bugs very difficult to debug.
For complete reference and examples of these casts, look for some books and tutorials, for example: http://www.cplusplus.com/doc/tutorial/typecasting/