【问题标题】:Why Visual C++ 6 complains on private destructor为什么 Visual C++ 6 抱怨私有析构函数
【发布时间】:2011-01-21 08:06:19
【问题描述】:

以下代码适用于 Visual C++ 2008。但是,当涉及到 Visual C++ 6 时,我收到以下错误。我可以知道为什么,以及如何修复错误,但仍使析构函数保持私有状态。

class X
{
public:
    static X& instance()
    {
        static X database;
        return database;
    }

private:

    X() {}                    // Private constructor
    ~X() {}                   // Private destructor
    X(const X&);              // Prevent copy-construction
    X& operator=(const X&);   // Prevent assignment
};

int main()
{
    X::instance();
}

C:\Projects\ttt6\main.cpp(178):错误 C2248:“X::~X”:无法访问在类“X”中声明的私有成员 C:\Projects\ttt6\main.cpp(175) :参见 'X::~X' 的声明

【问题讨论】:

  • 构造函数/析构函数不应该总是公开的吗?
  • @Aviator:构造函数不应该总是公开的。示例:对于抽象类,您只希望派生类调用构造函数(这就是您可以防止抽象类实例化的方法),因此您将其设为protected。对于单例,您只需要类的静态 CreateInstance() 方法来创建实例,因此您可以创建构造函数 private
  • @Scott:非常感谢。我现在明白了。
  • 此代码在 VC9 上也会出错。我不敢相信它可以在任何编译器上编译。
  • VC2008 是 VC9。有VC6 == VC98, VC7 == VC2002, VC7.1 == VC2003, VC8 = VC2005, VC9 == VC2008, VC10 = VC2010。

标签: c++


【解决方案1】:

fun() 中,您正在创建一个单独的对象aa,然后通过赋值运算符将a::instance() 返回的对象引用的值复制到它。这不起作用,因为构造函数和析构函数都是私有的。 aa 应该是参考:

a &aa = a::instance();

【讨论】:

  • 实际上它试图通过复制ctor复制它。
  • 对不起。我的代码示例中有一些错误。我已经修改了。代码在 VC6 中仍然报错,但在 VC2008 中通过。
  • @Yan:不会通过的,我保证;你的测试是错误的。给我们你的真实代码而不是示例代码。
  • 我提供了完整的代码(main函数的补充)。我测试了很多次。确认 VC2008 有效,但 VC6 无效。
  • 您刚刚更改的代码与您之前的代码匹配。您的新代码运行良好,格式良好,可以在任何符合标准的编译器上编译。相反,您的旧代码在所有符合标准的软件中都会出错。 也就是说,Visual Studio 6.0 不符合 标准,这是一个错误。我会添加一个答案。编辑: gf 打败了我。 :P
【解决方案2】:

当到达 fun() 的末尾时,你的变量将超出范围并调用析构函数。

看起来您正在尝试实现单例 - 也许您是这个意思?

a& aa = a::instance();

如果 aa 是引用而不是实例,那么在 fun() 结束时不会调用析构函数。

【讨论】:

  • 对不起。我的代码示例中有一些错误。我已经修改了。代码在 VC6 中仍然报错,但在 VC2008 中通过。
【解决方案3】:

修改后的示例显示了一个已确认的 VC6 编译器错误 - 常见的解决方法是简单地公开析构函数。

【讨论】:

【解决方案4】:

这只是 VC6 的错误。 VC6 非常有问题。您可以使用 std::auto_ptr 作为解决方法。

#include <memory>

class X
{
    friend std::auto_ptr<X>;
public:
    static X& instance()
    {
        static std::auto_ptr<X> database(new X);
        return *database;
    }
.....
};

并且,请将 instance() 实现移至 cpp 文件。抱歉,我不记得确切的情况,但是头文件中还有另一个 VC6 错误与单例实现。几年前我们在使用 VC6 时发生过几次崩溃。解决方法是将 instance() 实现移至 cpp。

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2012-11-22
    • 1970-01-01
    • 2015-06-09
    • 2020-08-12
    • 2016-02-27
    相关资源
    最近更新 更多