【问题标题】:C++ strange issue. Data member getting out of scopeC++ 奇怪的问题。数据成员超出范围
【发布时间】:2017-10-17 04:56:44
【问题描述】:

这段代码:

#include "stdafx.h"
#include <iostream>
using namespace std;
class singleTon
{
    float testVal;
public:
    singleTon()
    {
        cout << "Singleton created\n";
        testVal = 0.0;
    }
    ~singleTon()
    {
        cout << "Singleton deleted\n";
    }
    void setTest(float x)
    {
        testVal = x;
    }
    float getTest()
    {
        return testVal;
    }

};

class myClass
{
    singleTon s;

public:
    myClass()
    {
        cout << "myClass created\n";
    }
    ~myClass()
    {
        cout << "myClass deleted\n";
    }

    singleTon getSingleTon()
    {
        return s;
    }

};

int _tmain(int argc, _TCHAR* argv[])
{
    myClass m;
    m.getSingleTon().setTest(100);
    cout << "\ngetting" << m.getSingleTon().getTest();
    cout << "\nSetting:";
    m.getSingleTon().setTest(200);
    cout << "\ngetting" << m.getSingleTon().getTest();

    getchar();
    return 0;
}

在第一个setTest()之后:

m.getSingleTon().setTest(100);      

单例类的析构函数被调用。

但是,为什么?

我的理解是它仍然会在class myClass 中保存单例实例。我知道,如果我使用堆分配,它可能会起作用。但是这种风格有什么问题呢?问题出在哪里?

【问题讨论】:

  • 您按价值返回,这意味着您每次都在制作副本。您需要通过引用返回。
  • 删除你的单例的复制构造函数,你会看到你的错误。
  • 您似乎误解了应该如何实现real singleton pattern

标签: c++ scope static allocation


【解决方案1】:
singleTon getSingleTon()
{
    return s;
}

这个函数的返回类型既不是引用也不是指针,所以你将返回s按值,这意味着你正在复制它并返回一个副本。但是,如果您想修改存储在myClass 中的singleTon 的数据成员,则需要通过引用返回(也可以通过指针返回,但如果没有必要,通常不鼓励这样做)。您的代码必须更改为如下所示:

singleTon& getSingleTon()
{
    return s;
}

【讨论】:

  • 是的,但是...... OP 所拥有的不是单例。这需要首先解决。
  • @user4581301 当然需要解决,但这不是OP所要求的,他的代码不起作用的原因不是他没有正确理解单例的概念,而是他实际上犯了一个错误,这也可能发生在任何非单例相关的代码中,这就是我想要解决的问题。在我看来,关于单身人士的 OP 教育不应该是回答这个问题的重点。
【解决方案2】:

当您调用 getSinglton() 时,实际上是在 myClass 中获得了单例的副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2016-11-30
    • 1970-01-01
    • 2022-07-18
    相关资源
    最近更新 更多