这个成语是什么,什么时候应该使用?它解决了哪些问题?当使用C++ 11时,成语是否会改变?
虽然在许多地方已经提到过,但我们没有任何单一的"它是什么"问题和答案,所以在这里.以下是前面提到的地方的部分列表:
c++ c++-faq copy-constructor assignment-operator copy-and-swap
我想知道是否有人可以解释那些条款,因为我在许多地方遇到它们.我知道一些关于它们的基本理论,但不确定我所知道的是对还是错.
那么任何人都可以解释这些条款吗?
我知道在大多数情况下,我们不应该明确地调用析构函数.但是,我在C++ 11 Standard N3485第13.4.5节模板参数中看到了一个例子:
对具有类模板特化的类型的对象的显式析构函数调用可以显式指定template-arguments.例:
Run Code Online (Sandbox Code Playgroud)template<class T> struct A { ~A(); }; void f(A<int>* p, A<int>* q) { p->A<int>::~A(); // OK: destructor call q->A<int>::~A<int>(); // OK: destructor call }
在我看来,在这种情况下我们可以明确地调用析构函数,你能解释一下为什么吗?在这个例子中,这些析构函数的含义是什么意思?为什么他们合理?
另一个问题:
除了我们实现之外,我们可以明确地调用析构函数的情况是什么placement delete?
谢谢.
编辑:我从C++ FAQ中发现,我们不应该在局部变量上显式调用析构函数.
说,代码
class Derived: public Base {....}
Base* b_ptr = new( malloc(sizeof(Derived)) ) Base(1);
b_ptr->f(2);
Derived* d_ptr = new(b_ptr) Derived(3);
b_ptr->g(4);
d_ptr->f(5);
Run Code Online (Sandbox Code Playgroud)
似乎是合理的,LSP也很满意.
我怀疑当Base和Derived是POD时,此代码是标准允许的,否则不允许(因为vtbl ptr被覆盖).我的问题的第一部分是:请指出这种覆盖的准确前提条件.
可能存在其他标准允许的写入方式.
我的问题的第二部分是:还有其他方法吗?他们的确切先决条件是什么?
更新:我不想写这样的代码; 我对这种代码的理论可能性(或不可能)很感兴趣.所以,这是"标准纳粹"问题,不是"我怎么能......"的问题.(我的问题是否已移至其他stackoverflow站点?)
UPDATE2&4:析构函数怎么样?假设此代码的语义是"基础实例(通过衍生实例片段(破坏性地)更新").让我们假设,为简单起见,Base类有一个简单的析构函数.
更新3:对我来说最有趣的是访问途径的有效性b_ptr->g(4)
请考虑以下示例:
#include <iostream>
struct foo {
void fun() const { std::cout << "foo::fun()" << std::endl; }
};
auto main() -> int {
foo f;
f.fun();
f.foo::fun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如上例所示,成员函数foo::fun()以两种不同的方式引发.
在第二个调用(即,f.foo::fun())中,成员类的范围foo::fun()被明确消除歧义/已解决.
问题:
f.fun()和f.foo::fun())?