从基类方法调用派生类的静态方法

时间:2015-02-08 23:51:40

标签: c++ inheritance casting static-methods dynamic-cast

我想实现一个方法CastTo(classId),它返回classId参数与参数匹配的基础对象的地址,否则将返回 nullptr

class A {
public:
    const std::string WhoAmI () { return "A"; }
    static const std::string ClassId() { return "A"; }
    const void* CastTo(const std::string& classId) const {
        if (classId == ClassId())   return dynamic_cast<const A*>(this);
        if (classId == B.ClassId()) return dynamic_cast<const B*>(this); //*
        if (classId == C.ClassId()) return dynamic_cast<const C*>(this); //*
        return nullptr;
    }
    //more methods
};

class B : public A{
public:
    const std::string WhoAmI() { return "B"; }
    static const std::string ClassId() { return "B"; }
    const void* CastTo(const std::string& classId) const {
        if (classId == A.ClassId()) return dynamic_cast<const A*>(this); //*
        if (classId == ClassId())   return dynamic_cast<const B*>(this);
        if (classId == C.ClassId()) return dynamic_cast<const C*>(this); //*
        return nullptr;
    }
    //more methods
};

class C : public B{
public:
    const std::string WhoAmI() { return "C"; }
    static const std::string ClassId() { return "C"; }
    const void* CastTo(const std::string& classId) const {
        if (classId == A.ClassId()) return dynamic_cast<const A*>(this); //*
        if (classId == B.ClassId()) return dynamic_cast<const B*>(this); //*
        if (classId == ClassId())   return dynamic_cast<const C*>(this);
        return nullptr;
    }
    //more methods
};

在注释行上,我收到错误“typename is not allowed”。我也试过用' - &gt;'代替 '。'但错误仍然存​​在。 我无法理解为什么上面的代码不起作用,因为这些方法被声明为静态。

这是作业的一部分,所以它必须按照我描述的方式工作,并且以下测试代码必须正常。

A* a = new C();
assert(a->Cast<C>().WhoAmI() == "C"); //Cast is a template used for 
assert(a->Cast<B>().WhoAmI() == "B"); //calling CastTo
assert(a->Cast<A>().WhoAmI() == "A");
B* b = a->Cast<B>();
C* c = a->Cast<C>();

使用的模板:

template <typename T> T* Cast (void)
{ return static_cast<T*>(CastTo(T::ClassId()); }
template <typename T> const T* Cast (void) const
{ return static_cast<T*>(CastTo(T::ClassId()); }

PS:我也试过使用B :: ClassId(),但后来我得到错误“'B'不是类或名称空间名称”,但只有当我从base调用派生时。

PS1:我不知道代码是否能像我想要的那样工作,因为我还没有能够摆脱错误。

1 个答案:

答案 0 :(得分:0)

A::CastTo中的语法错误:

    if (classId == B.ClassId()) return dynamic_cast<const B*>(this); //*
    if (classId == C.ClassId()) return dynamic_cast<const C*>(this);

你需要使用

    if (classId == B::ClassId()) return dynamic_cast<const B*>(this); //*
    if (classId == C::ClassId()) return dynamic_cast<const C*>(this);

需要在B::CastToC::CastTo中进行类似的更改。

但是,要实现此功能,您必须在类外部实现该功能,最好是在.cpp文件中,您可以使用#include "B.h"#include "C.h"

更好的方法

class A {
public:
    static const std::string ClassId() { return "A"; }

    // Class A should know nothing about its derived classes.
    virtual const void* CastTo(const std::string& classId) const {
        if (classId == ClassId())   return (this);
        return nullptr;
    }
};

class B : public A{
public:
    static const std::string ClassId() { return "B"; }

    // Class B knows about itself and its base class, noting else.
    virtual const void* CastTo(const std::string& classId) const {
       if (classId == ClassId())   return (this);
       return A::ClassId(classId);
    }
};

class C : public B{
public:
    static const std::string ClassId() { return "C"; }

    // Class C knows about itself and its base class, noting else.
    virtual const void* CastTo(const std::string& classId) const {
       if (classId == ClassId())   return (this);
       return A::ClassId(classId);
    }
};