Область объекта, созданного с использованием нового

Я изучаю C ++ как хобби и борюсь с использованием «new» для динамического создания объекта класса. Я читал, что динамически создаваемые классы не теряют своей области видимости, но это не похоже на мой простой пример.

При выполнении значение ‘testValue1’ устанавливается равным 555 в конструкторе и печатается. Когда элемент управления возвращается в main, «testvalue», к сожалению, устанавливается в 0 (или не определен — не уверен). Я могу установить значение внутри main, и значение должным образом поддерживается как внутри main, так и в цикле for.

Проблема: я не понимаю, почему инициализированное значение 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;
}

1

Решение

Это утверждение:

int testValue1= 555;

объявляет локальная переменная, отличается от данных члена с тем же именем.

Так что это не меняет значение члена.

Вместо этого сделайте, например,

testValue1= 555;

Или используйте список инициализатора памяти конструктора, например так:

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

Другие решения

Вы определили другую переменную в конструкторе generalVars и значение init для 555, чтобы инициализировать член 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;
}
2

Происходят две вещи:

1) Вы повторно объявляете testValue1 здесь, помещая int перед:

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;
}

Далее это не совсем проблема, но следует отметить:

Вам не нужно большую часть времени распределять вещи с помощью new в C ++. Вы должны предпочесть стекированные объекты

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
По вопросам рекламы [email protected]