【问题标题】:How can I call const member function from destructor如何从析构函数调用 const 成员函数
【发布时间】:2015-06-13 18:48:29
【问题描述】:

当 const 对象被销毁时,有没有办法从析构函数中调用 const 成员函数?

考虑:

struct My_type { 
    ~My_type () { 
        show ();
    }

    void show () { 
        cout << "void show ()" << endl;
    }
    void show () const { 
        cout << "void show () const" << endl;
    }
};

及用法:

My_type mt;
const My_type cmt;
mt.show ();
cmt.show ();

输出:

void show ()
void show () const
void show ()
void show ()

有人能解释一下为什么当 cmt 被销毁时没有调用 const 版本的 show 吗?

【问题讨论】:

  • const_cast&lt;const MyType*&gt;(this)-&gt;show(); ?不过,我很好奇你的用例。
  • @NeilKirk 你正在销毁对象及其成员,这怎么可能是“const”?
  • @NeilKirk 在构造过程中修改的方式相同
  • 我担心您需要两个(交互)类型“My_type”和“My_c​​onst_type”来实现您的目标。
  • @NeilKirk:我记得曾经希望const 有构造函数和析构函数的重载。我不记得用例了,但它与希望将某些内容作为公共成员存储在可变对象中的值或通过 const-ref 存储在 const 对象中有关。

标签: c++ c++11 destructor


【解决方案1】:

const 实例上调用非常量重载的原因是因为在销毁期间不考虑当前实例上的 cv 限定符。 [class.dtor]/p2:

析构函数用于销毁其类类型的对象。不应采用析构函数的地址。 可以为 const、volatile 或 const volatile 对象调用析构函数。 constvolatile 语义 (7.1.6.1) 不适用于正在销毁的对象。 最衍生对象 (1.8) 的析构函数启动。

您可以使用简单地将*this 绑定到对const 的引用来获得您需要的行为:

~My_type() { 
    My_type const& ref(*this);
    ref.show();
}

或者,也许您可​​以使用存储引用并在其自己的析构函数中调用 show() 的包装器:

template<class T>
struct MyTypeWrapper : std::remove_cv_t<T> {
    using Base = std::remove_cv_t<T>;
    using Base::Base;

    T&       get()       { return ref; }
    T const& get() const { return ref; }

    ~MyTypeWrapper() { ref.show(); }
private:
    T& ref = static_cast<T&>(*this);
};

【讨论】:

  • 恐怕代码不会有OP需要的行为。他想要只为 const 对象调用 const 方法。我不确定这是否可能。
  • 当然可以用 std::is_const 和一些模板技巧来完成。
  • @Robinson 真的吗?在ctor或dtor内部?怎么样?
  • 上面的包装器是最干净的方法。我想的那个很笨重。
  • 顺便说一句,我想我更愿意将名称 cthis 保留为指针而不是引用。
【解决方案2】:

析构函数应该对其成员进行清理/从某种意义上说,析构函数应该修改当前对象整体的内容进行清理。所以,析构函数必须是非常量的。而且,一个非常量成员函数只能调用所有非常量成员函数。这说明了。

【讨论】:

  • 非常量成员函数可以调用常量非常量成员函数。 OP 示例中显示的行为通常是出乎意料的。
【解决方案3】:

我喜欢这个问题。

析构函数不能是 const。它们的行为类似于任何非常量方法。非常量方法调用非常量方法。

但是,在析构函数中调用 const 方法是有充分理由的。 (例如记录)。从非常量方法调用非常量和常量版本,调用非常量。

要调用 const,可以使用 static_cast。但是......你无法确定何时施放。 (换句话说:你不知道你自己是否是 const 的)。

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 2011-06-04
    • 1970-01-01
    • 2018-05-13
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2011-01-16
    相关资源
    最近更新 更多