如何在以下程序中以私有方式调用派生类析构函数
How does the derived class destructor get invoked being private in the following program?
#include<iostream>
class base
{
public:
virtual ~base(){std::cout << "basen";}
};
class derived : public base
{
private:
~derived(){std::cout << "derivedn";} /* destructor is private */
};
int main()
{
base *pt= new derived;
delete pt;
}
上面的程序编译并运行良好。派生类析构函数如何被调用为私有?
这不仅会发生在析构函数中。
您可以使用私有函数覆盖任何虚拟公共函数。
#include<iostream>
class base
{
public:
virtual void x(){std::cout << "basen";}
};
class derived : public base
{
private:
void x(){std::cout << "derivedn"; base::x();}
};
int main()
{
base *pt= new derived;
pt->x(); //OK
//((derived *)pt)->x(); //error: ‘virtual void derived::x()’ is private
derived *pt2= new derived;
//pt2->x(); //error: ‘virtual void derived::x()’ is private
((base *)pt2)->x(); //OK
}
这样做的好处/缺点是您必须使用指向 base 的指针来访问此方法。此功能是将公共 API 与自定义实现分离的方法之一。
因此,换句话说,您的析构函数被调用,因为它在 base 中被声明为公共的,并且您通过指向 base 的指针将其调用。
这可能令人惊讶,但如果你仔细想想,这是完全合乎逻辑的。
编译器看到的是删除指向基的指针,该指针具有可访问的析构函数。所以它没有理由抱怨你正在做的事情。偶然地,它是一个虚拟的析构函数,但这也不是值得抱怨的事情。
在运行时,将调用虚拟析构函数。由于事实证明指向基的指针实际上指向派生对象,因此需要首先调用派生构造函数。
"但那个是私人的!">你说。没错,但是,在运行时没有公共/私有的概念。所以,再一次,没有理由发生任何不好的事情。不会生成任何错误。
相关文章:
- 重载方法的方式会在使用临时调用时生成编译器错误
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 是否可以使用非常量指针调用非常量函数,以及当两个unique_ptrs指向同一个对象时程序的行为方式?
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?
- 为什么我以前调用析构函数的方式会导致模因问题
- 以独立方式从 C 调用C++
- 调用多个选定函数并节省 RAM 的最佳方式
- 有没有办法在函数以编程方式返回的引用上多次调用函数? -元组动态访问
- 虚拟和非虚拟成员函数的调用方式有什么区别?
- 这些不同的方式在“ this”上调用操作员有什么区别
- 如何根据其ARITY(或编译时已知的其他信息)以不同的方式调用函数对象
- 是否可以在main中以类似于Boost.MinimalTestFacility的方式调用Boost.UnitTest测试
- 如果从动态分配的对象调用方法,是否可以以某种方式内联(编译器优化)
- 这将是在将函数分配给变量或一次又一次地调用函数之间使用函数结果的最佳方式
- 函数调用时局部变量在堆栈中的组织方式
- 通过以下方式调用函数有什么区别
- 此C++代码中以何种方式调用函数
- Opencv 函数只能以 C 代码方式调用,而不能以C++方式调用
- 为什么GetLastError()根据调用方式返回0或2 ?
- __cdecl、__stdcall和__fastcall的调用方式完全相同