C++ 具有纯虚函数的继承
C++ Inheritance with pure virtual functions
>我正在尝试创建一个用作基本对象的类,然后将其子类化(=实现)以服务于各种目的。
我想定义一个或多个纯虚函数,以便无论基类的子类是什么,都是必需的,并且不要忘记实现它们。
有一个警告,纯虚函数的签名包括基本对象的类型。一旦子类化,函数定义当然不再与基类定义匹配。例如:
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
,但是我不能利用派生类中的任何对象。
我必须使用铸造才能完成此操作吗?
如果我的意图/问题不清楚,请告诉我。
无需更改函数签名。请看以下内容:
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<>
并在该强制转换失败时引发异常。
目前还不清楚你想实现什么。假设编译器允许您执行此操作(或者通过强制转换执行此操作),那么它将在类型系统中打开以下漏洞:
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());
}
你的设计可能是错误的。
我假设编译器接受,但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;
};
但请注意,如果参数不属于正确的类,则运行时检查将引发异常。
实现此目的的一种方法是使用模板,并使参数成为派生类型的类型
template <typename T>
class BaseItem {
public:
virtual std::string getDifferences(const T& item) = 0;
};
class DerivedClass : public BaseItem<DerivedClass> {
public:
virtual std::string getDifferences(const DerivedClass& item) {
// Implement it here
}
};
如果给定的 BaseItem 是 DerivedClass 实例,则应使用 BaseItem 到 DerivedClass 的强制转换 + 运行时检查。
相关文章:
- C++虚函数继承
- 名称隐藏对静态函数继承的实例使用
- C++ std::vector 中的虚拟析构函数继承
- 具有相同名称的类的构造函数继承
- 多复制构造函数继承中的惊人行为
- CRTP 和复制/移动赋值/构造函数继承
- 复制构造函数继承动态分配的数组
- 谷神星求解器成本函数继承错误:模板可能不是虚拟的
- 无法从 c++ 中的构造函数继承
- 在构造函数继承中使用默认构造函数
- 如何定义从虚拟函数继承的静态函数
- 调用超类函数继承 c++
- 构造函数继承和直接成员初始化
- c++ 不明确的双非虚函数继承
- C++ - 使用私有参数的构造函数继承
- 通过可变参数模板进行C++11构造函数继承
- 使用模板进行函数继承
- C++11构造函数继承和不带参数的构造函数
- 函数继承问题
- C++11 - 构造函数继承