我正在尝试创建一个类作为基对象,然后将其子类化(=实现)以服务于各种目的。
我想定义一个或多个纯虚函数,这样无论基类是什么子类,都是必需的,并且不会忘记实现它们。
有一点需要注意,纯虚函数的签名包括基对象的类型。一旦划分了子类,函数定义当然就不再与基类定义相匹配。例如:
class BaseItem
{
public:
virtual std::string getDifferences(const BaseItem& item) = 0;
}所以,在派生类中,我想做的是:
class DerivedClass : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
std::string derivedItemCustomObject;
}编译器当然不会接受。当然,我可以将其设置为BaseItem,但这样我就不能利用派生类中的任何对象。
我必须使用强制转换来完成此操作吗?
如果我的意图/问题不清楚,请告诉我。
发布于 2011-05-15 12:50:57
无需更改函数签名即可实现。请看以下内容:
class BaseItem
{public:
virtual std::string getDifferences(const BaseItem& item) = 0;
};
class DerivedClass : public BaseItem
{public:
virtual std::string getDifferences(const BaseItem& item) // keep it as it's
{
const DerivedClass& derivedItem = static_cast<const DerivedClass&>(item);
}
};可以毫无畏惧地使用static_cast<>,因为DerivedClass::getDifferences()只为DerivedClass对象调用。为了说明,
BaseItem *p = new DerivedClass;
DerivedClass obj;
p->getDifferences(obj); // this always invoke DerivedClass::getDifferences如果您担心有时可能会将任何其他派生类对象作为参数传递给该方法,那么请改用dynamic_cast<>,并在转换失败时抛出exception。
发布于 2011-05-15 04:24:03
现在还不清楚你想要实现什么。假设编译器允许您这样做(或者您是通过强制转换的方式做到这一点),那么它将在类型系统中打开以下漏洞:
class BaseItem
{
public:
virtual std::string getDifferences(const BaseItem& item) = 0;
};
class DerivedClass : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass& item)
{
item.f();
// ...
}
void f() const {}
};
class DerivedClass2 : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass2& item) { ... }
};
void g()
{
BaseItem* x = new DerivedClass;
// oops, calls DerivedClass::f on an instance of DerivedClass2
x->getDifferences(DerivedClass2());
}您的设计可能是错误的。
发布于 2011-05-15 04:30:16
我假设编译器接受,但是DerivedClass::getDifferences没有覆盖BaseItem::getDifferences。下面是一种实现你明显想要的东西的方法
template <typename T>
class DerivedHelper: public BaseItem {
public:
virtual std::string getDifferences(const BaseItem& item) {
getDifferences(dynamic_cast<const T&>(item));
}
virtual std::string getDifferences(const T& item) = 0;
};
class DerivedClass : public DerivedHelper<DerivedClass>
{
public:
// not more needed but providing it will hide getDifferences(const BaseItem& item)
// helping to statically catch some cases where a bad argument type is used.
virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
std::string derivedItemCustomObject;
};但请注意,如果参数不是正确的类,运行时检查将抛出异常。
https://stackoverflow.com/questions/6004501
复制相似问题