我想实现一个方法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:我不知道代码是否能像我想要的那样工作,因为我还没有能够摆脱错误。
答案 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::CastTo
和C::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);
}
};