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

Call static method of derived class from base class method

我想实现一个方法 CastTo(classId),其中 returns 其 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"。我也尝试过使用“->”而不是“。”但错误仍然存​​在。 我不明白为什么上面的代码不能工作,因为这些方法被声明为静态的。

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

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' 不是 class 或命名空间名称”,但是只有当我调用 derived from base 时。

PS1:我不知道代码是否会按我希望的那样工作,因为我还没有能够消除错误。

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 中进行类似的更改。

但是,要使其正常工作,您必须在 class 之外实现该功能,最好是在您可以使用 #include "B.h"#include "C.h" 的 .cpp 文件中。

更好的方法

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