gpt4 book ai didi

c++ - 什么时候可以确定我可以继承c++类?

转载 作者:行者123 更新时间:2023-12-01 14:35:04 26 4
gpt4 key购买 nike

假设我使用一个包含各种类的外部库。我什么时候可以安全地继承其中一个类?我知道基类必须有一个虚析构函数。在将该类用作基类之前,还有什么我应该检查的吗?我能否确定仅当文档如此说明时它是安全的?

最佳答案

如果文档声明派生类型是安全的,请按照文档进行操作。如果出于某种原因,它的行为方式与文档不符,那么这是库的问题,是作者需要修复或提供解决方法的错误,因为他们没有 promise 他们保证的 API在文档中。


任何不是 final 的类型都可以“安全地”派生;更重要的是如何处理和销毁这种类型。如果您从没有 virtual 析构函数的类型继承,这不会破坏任何东西;如果您从基句柄中销毁派生类型的析构函数,它只会阻止调用派生类型的析构函数。

如果您只销毁从句柄到派生类型的类型(例如,您要么具体持有它,要么从不销毁它从句柄到基类),那么这没有任何后果。

为了更好地解释我的观点,想象一下以下层次结构:

class Base {
public:
// No virtual destructor
...
};

class Derived : public Base {
public:
...
private:
std::string m_something; // some leakable object
};

Base 派生Derived 是完全安全的。重要的是它如何被销毁,是否会出现问题。为此,需要考虑两种不同的情况:自动情况和动态情况。

自动对象

自动类型(“按值”类型)是安全的,无论它们是否具有静态生命周期

auto d = Derived{ ... };
static auto sd = Derived{ ... };

在它们的生命周期结束时,析构函数 Derived::~Derived 将被调用,因为类型是具体已知的

动态对象

动态对象不会自行销毁。他们的资源需要最终清理,或者通过智能指针中的 RAII 自动清理,通过调用 delete,或者通过显式调用 ~T() 并释放内存。

如果它们被派生类型的句柄销毁,它们仍然是安全的,但如果它们被基类的句柄销毁,它们将不安全。

auto* d1 = new Derived{ ... }; 
auto* d2 = new Derived{ ... };

// Deleting as a pointer to Base; ~Derived won't be called because ~Base is virtual
// This would be a memory leak
delete static_cast<Base*>(d1); // bad

// Deleting as a pointer to Derived -- ~Derived will be called, this is fine
delete d2; // good

在智能指针类型方面:

共享指针

shared_ptr 类型是安全的,因为它们总是从具体类型中销毁对象——即使它们被别名为基类。

void accept_base(std::shared_ptr<Base> b);

auto d = std::make_shared<Derived>(...);

// still safe
accept_base(std::move(d));
唯一指针

unique_ptr 类型默认情况下不安全,因为默认删除器根据 unique_ptrT 类型进行删除>.

例如:

auto d = std::make_unique<Derived>(...);

auto b = std::unique_ptr<Base>{std::move(d)};

// b will be destroyed at end of scope by calling ~Base, which is not virtual!

即使说了所有这些:如果您使用的库明确声明您要派生某个 XYZ 类,那么您仍然应该假设这就是应该使用该类的方式。届时,如果发生不希望发生的事情,库维护者将负责确保他们的代码按照记录执行,因为它是他们明确声明的 API 的一部分。

关于c++ - 什么时候可以确定我可以继承c++类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63376878/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com