使用new创建的对象的范围

时间:2014-04-24 00:05:24

标签: c++ named-scope

我正在学习C ++作为一种爱好,并且正在努力使用“new”来动态创建一个类对象。我已经读过动态创建的类不会丢失范围,但这似乎不适用于我的简单示例。

执行时,'testValue1'的值在构造函数中设置为555并打印。当控件返回main时,'testvalue'很遗憾地设置为0(或未定义 - 不确定)。我可以在main中设置值,并在main和for循环中正确维护该值。

问题:我不明白为什么当控制返回到main时,不保持初始值555。我知道我做错了什么或者没有正确理解动态分配的类对象的范围......任何帮助都表示赞赏。以下是示例代码:

//main.cpp
#include <iostream>  
using namespace std;

class generalVars
{
    private:    
    public:
    //data attributes
    int testValue1; 

    //constructor
    generalVars()
    {
        cout << "I am in general vars constructor" << endl;
        int testValue1= 555;
        cout << "testValue1 has been set " << testValue1 << endl;
    }

    ~generalVars(void)
    {
        cout << "I am in general vars destructor" << endl;
    };
};


int main(int argc, char *argv[])
{
    cout << "I am in Main" << endl;
    generalVars* myGeneralVars = new generalVars; //create on heap

    cout << "Main1 testvalue1 = " << myGeneralVars->testValue1 << endl;

    myGeneralVars->testValue1 = 777;
    cout << "Main2 testvalue1 = " << myGeneralVars->testValue1 << endl;

    for (int i=0; i<= 3; i++) 
    {
        cout << "Inside while loop..." << endl;
        cout << "Main3 " << i << " testvalue1 = " << myGeneralVars->testValue1 << endl;
    }
    delete myGeneralVars; //delete from heap
    return 0;
}

3 个答案:

答案 0 :(得分:4)

本声明:

int testValue1= 555;

声明本地变量,与同名的数据成员不同。

所以它不会改变成员的价值。

相反,例如。

testValue1= 555;

或者使用构造函数的内存初始化列表,如下所示:

generalVars()
    : testValue1( 555 )
{
    cout << "I am in general vars constructor" << endl;
    cout << "testValue1 has been set " << testValue1 << endl;
}

答案 1 :(得分:2)

正在发生两件事:

1)通过将int放在前面来重新声明testValue1:

generalVars()
{
    cout << "I am in general vars constructor" << endl;
    int testValue1= 555; //right here!
    cout << "testValue1 has been set " << testValue1 << endl;
}

这将使用同名的新唯一变量隐藏类自己的testValue1实例。您可以像这样引用它们:

generalVars()
{
    cout << "I am in general vars constructor" << endl;
    int testValue1= 555; //note, still has int
    cout << "testValue1 has been set " << testValue1 << endl;
    cout << "this->testValue1 has not been set and is " << this->testValue1 << endl;
    this->testValue1 = 555; //note, this->
    cout << "this->testValue1 has been set " << this->testValue1<< endl;
}

或者您可以避免名称冲突并正常引用它:

generalVars()
{
    cout << "I am in general vars constructor" << endl;
    testValue1= 555; //note, no int.  This is identical to this->testValue1
    cout << "testValue1 has been set " << testValue1 << endl;
}

接下来不是一个真正的问题,但应该注意:

在大多数情况下,您不需要使用C ++中的new分配内容。您应该更喜欢堆栈分配的对象

generalVars myObject;

而不是:

generalVars *myObject = new generalVars();
...
delete myObject;

或者,如果您确实想要创建堆分配对象:

auto myObject  = std::make_unique<generalVars>();

或者,如果您需要多个句柄:

auto myObject  = std::make_shared<generalVars>();

unique_ptr和shared_ptr示例不需要显式删除。当指针对象超出范围时,将删除堆分配。这特别有助于异常安全。

答案 2 :(得分:2)

您在generalVars构造函数中定义了另一个变量,并将init值定义为555,对于init成员testValue1,您不需要在构造函数中再次定义它。

更新

generalVars()
{
    cout << "I am in general vars constructor" << endl;
    int testValue1= 555; // this defines another testValue1 variable. it's different from member testValue1
    cout << "testValue1 has been set " << testValue1 << endl;
}

generalVars()
{
    cout << "I am in general vars constructor" << endl;
    testValue1= 555;  // Note, removed int 
    cout << "testValue1 has been set " << testValue1 << endl;
}