作为一个新的C ++爱好者,我仍然在努力理解使用" new"创建的类对象的范围。我以为我通过使用" new"来实例化一个动态对象,所以程序的所有部分(例如,在其他函数中)都可以访问类(和成员),因为它不是在堆栈。
在下面的代码中,我设置了' tesValue1'的初始值。至" 111"在构造函数中,然后尝试将其更新为" 222"在' check_accessibility'功能。这无法编译错误" myGeneralVars"未在此[函数调用]范围内声明。
非常感谢任何帮助。
//main.cpp
#include <iostream>
using namespace std;
class generalVars
{
private:
public:
//data attributes
int testValue1;
//constructor
generalVars()
{
testValue1= 111;
}
~generalVars(void)
{
cout << "destructor code here" << endl;
};
};
void check_accessibility() {
myGeneralVars->testValue1= 222;
}
int main(int argc, char *argv[])
{
generalVars* myGeneralVars = new generalVars; //create on heap
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //value set in constructor
check_accessibility(); //sets testValue to new value
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //want "222"
delete myGeneralVars; //delete from heap
return 0;
}
答案 0 :(得分:2)
它有你决定的生命。
C ++使用存储持续时间的概念:对象的生命周期取决于其实例化的位置和方式。存储持续时间有三种(四种):
静态存储持续时间:对象将在程序启动时初始化,并在程序完成时被破坏。全局变量和静态类属性具有静态存储持续时间。
自动存储持续时间:对象的生命周期由声明变量的作用域的生命周期定义。因此,当函数启动并结束时,局部变量的生命周期开始当功能结束时对于非静态类数据成员也是如此:它的生命周期在对象的生命周期开始时开始,并在对象的生命周期结束时结束。
动态存储时间:使用new
和delete
在动态内存上创建对象,生命周期由用户决定。当用户new
生命周期开始时,delete
生命周期何时结束。
有关详细信息,请参阅this documentation page。
在您的情况下,使用指针变量实例化具有动态存储持续时间的对象,以保存其内存地址(对象的位置)。由于你从未在该指针上执行delete
,因此对象的生命周期永远不会结束:这就是内存泄漏。
此外,您尝试访问在其他函数(check_accessibility)中的一个函数(main)中定义的变量。当然,这个变量在主要部分之外是不可见的。但这与动态存储持续时间无关,它只是一个简单的名称查找问题。谁告诉你存储持续时间有一些相关的或取决于名称/变量可访问性完全错误。
答案 1 :(得分:0)
在函数check_accessibility中,使用尚未声明的名称myGeneralVars。
void check_accessibility() {
myGeneralVars->testValue1= 222;
}
因此编译器会发错。
在使用任何名称之前,必须声明它。
您可以按以下方式编写该功能
void check_accessibility( generalVars* myGeneralVars ) {
myGeneralVars->testValue1= 222;
}
并将其命名为
check_accessibility( myGeneralVars );
答案 2 :(得分:0)
myGeneralVars
不知道 check_accessibility()
,因此您无法访问该变量。相反,尝试将其作为参数传递。
void check_accessibility(generalVars* genVar) {
genVar->testValue1= 222;
}
int main(int argc, char *argv[])
{
generalVars* myGeneralVars = new generalVars; //create on heap
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //value set in constructor
check_accessibility(myGeneralVars); //sets testValue to new value
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //want "222"
delete myGeneralVars; //delete from heap
return 0;
}
答案 3 :(得分:0)
myGeneralVar仅在main()范围内有效,因此check_accessibility()无法访问它。您必须先在全局范围内(函数外定义)或通过将其作为参数传递给main()中的check_accessibility()来声明它。请记住,主要功能不是全局范围,您可能会想到。 main()只是一个像其他函数一样的函数,并且有自己的范围。
答案 4 :(得分:0)
由于你是一个爱好者和初学者,让我们尽早让你走上正确的轨道,这样你就可以从你的爱好中获得更多的乐趣和享受。
考虑我在这里所做的改变,采用的原则会使你的程序在复杂性增加时更加优雅,健壮和令人愉悦。
//main.cpp
#include <iostream>
#include <memory>
using namespace std;
class generalVars
{
private:
public:
//data attributes
int testValue1;
//constructor
generalVars()
: testValue1(111)
{
}
~generalVars(void)
{
// if the class is carefully written using std:: objects
// you will rarely need to define a destructor
cout << "destructor code here" << endl;
};
};
// pass a reference to a mutable object to ensure that logic
// is performed on the object and not on its lifetime
void check_accessibility(generalVars& gv) {
gv.testValue1= 222;
}
int main(int argc, char *argv[])
{
unique_ptr<generalVars> myGeneralVars(new generalVars); //create on heap *safely*
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //value set in constructor
check_accessibility(*myGeneralVars); //sets testValue to new value
cout << "Main testvalue1 = " << myGeneralVars->testValue1 << endl; //want "222"
// no delete necessary - unique_ptr's destructor takes care of it
return 0;
}
输出:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
Main testvalue1 = 111
Main testvalue1 = 222
destructor code here
答案 5 :(得分:0)
此外,您可以在generalVars类中定义check_accessibility()函数,并从main调用它 mygeneralVars-&GT; check_accessibility();