为方便起见,我使用以下方法。即在较大程序中访问同一myapp实例的便捷方法。代码在我的机器上编译并正确运行,但是想问一下是否有人发现这种方法存在任何问题?
例如,将此ptr分配给构造函数中的the_app?这可以吗?我担心的是物体仍在建造中。但是如果最后一行构造函数那么好吗?或者是因为它是一个指针所以无关紧要,因为只要在完全构造时使用ptr到完整对象?
#include <iostream>
using namespace std;
class myapp
{
public:
myapp() : m_data(0)
{
the_app = this;
}
void DoIt() { cout << "doing it\n"; }
static myapp* the_app;
private:
int m_data;
};
myapp* myapp::the_app = 0;
int main(int argc, char* argv[])
{
myapp app;
app.DoIt(); //doing it using member function
myapp::the_app->DoIt(); //accessing using static ptr
return 0;
}
答案 0 :(得分:1)
这是按预期工作的。 但有几个问题:
答案 1 :(得分:1)
如果你所追求的是静态访问类的单个实例,那么 你可能想看看 C++ Singleton design pattern
答案 2 :(得分:0)
不行:
{
myapp app;
}
myapp::the_app->DoIt();
这是非法的,因为myapp::the_app
在这个阶段是一个悬空指针。
答案 3 :(得分:0)
如果您要初始化它,那么不,您必须明确定义静态成员变量和initialize them there:
如果要显式初始化数据成员,则使用初始化程序 必须提供定义
每个类只有一个,并在所有对象之间共享。静态数据成员可以通过静态函数成员访问。
如果您不打算初始化,那么您需要考虑到您的类的每个新实例都会覆盖该值的帐户,并且您始终会创建最后一个指针。当你的类被破坏时 - 指针可能变得无效。
答案 4 :(得分:0)
我可以看到的问题:
myapp
析构函数中清除,因为您还没有写入。{li>如果您的真实代码没有在main()
的堆栈上,指针可能会在对象被销毁后继续存在。myapp
初始化的其余部分之前重新排序。根据平台的不同,分配指针可能不是原子的。答案 5 :(得分:0)
正如其他人所指出的,问题是:
您可以通过添加
来缓解前两个问题assert(the_app == NULL);
到你的构造函数和
the_app = NULL;
到您的析构函数。
浮现在脑海中的其他解决方案:
std::scoped_ptr<my_app> the_global_app;
...如果您使用单个全局对象,您可能会承认您正在使用全局变量。在main
函数中:
int main(int argc, char* argv[])
{
the_global_app.reset( new myapp() ); // or a derived class
the_global_app->DoIt(); //accessing using static ptr
return 0;
}
如果您不打算从myapp
派生,您甚至可能想要使用普通的全局变量:
myapp the_global_app;
int main(int argc, char* argv[])
{
the_global_app.DoIt(); //accessing using static ptr
return 0;
}
...但是你需要知道在不同的源文件中定义的其他全局对象可能尚未初始化(尽管保证std::cout
可用)。