我正在用QT编写一个c ++应用程序,专注于速度优化。 我希望有一些全局对象具有不同线程的只读访问权限。 在打开线程之前,我必须初始化全局对象并用数据填充它们。
如何保护全局对象的设置功能,但仍然可以从主功能访问?
现在的示例代码如下:
myClass.h
class MyObjectClass {
public:
void SetSome(const QList<QString> &value);
QList<QString> GetSome() const;
private:
QList<QString> m_myMember;
};
main.cpp
#include "global.h" // some like: extern MyObjectClass g_InihalizedInMain;
#include "anyThread.h"
int main(){
g_InitializedInMain.SetSome() // This Shut work
MyThread thread;
thread.start();
//..
return 0;
}
anyThread.cpp:
#include "global.h"
void thread::run()
{
MyObjectClass newObject = g_InihalizedInMain; //This shut work
g_InitializedInMain.GetSome(); //This shut work
g_InitializedInMain.SetSome(); //This shut not work and give me an error during compile time
newObject.SetSome(); //This shut work
}
如果您对我有一些设计理念,我会很高兴,非常感谢!
答案 0 :(得分:0)
class MyPrivateObjectClass : private MyObjectClass
{
public:
friend void main();
};
extern MyPrivateObjectClass g_InitializedInMain;
答案 1 :(得分:0)
创建全局变量static
,这意味着只有一个源文件可以访问它。然后,您可以提供可以从其他线程读取数据的访问器函数。
答案 2 :(得分:0)
对于初学者,我会不惜一切代价避免全局变量。
你可以做的而不是全局变量是在main中实例化一个变量(或者
动态地,或在堆栈上本地,取决于您的偏好)
并将其设置在线程对象中(这称为dependency injection
)
要仅从main控制MyObjectClass上的设置属性,我可以考虑2个选项:
通过main中的构造函数设置所有MyObjectClass属性,从而允许您删除setter,但保留getter。 MyObjectClass是不可变的。
创建一个上下文对象,其中包含MyObjectClass的所有可设置属性。此上下文对象只能传递给MyObjectClass构造函数。应该在main中创建上下文对象,调用适当的setter,然后在从main实例化时传递给MyObjectClass。 MyObjectClass类在内部使用来自上下文对象的这些属性,但没有为它们设置setter。当然,MyObjectClass上可以使用getter来获取内部上下文对象的值。 MyObjectClass是不可变的,但这种方式更灵活。
我更喜欢第二种选择。这是一个代码示例:
myClass.h
class MyObjectContext {
public:
void SetSome(const QList<QString> &value);
QList<QString> GetSome() const;
private:
QList<QString> m_myMember;
};
class MyObjectClass {
public:
MyObjectClass(MyObjectContext *context) : context_(context) {}
QList<QString> GetSome() const {return context_->GetSome();}
// Put the rest of the important stuff here
private:
MyObjectContext *context_;
MyObjectClass(); // explicitly stating that the default ctor cant be called
};
的main.cpp
int main(){
// creating these objects on the stack, you may need
// to create them dynamically, its up to you
MyObjectContext context;
context.SetSome() // This Should work
MyObjectClass moc(&context);
MyThread thread(&moc);
thread.start();
//..
return 0;
}
anyThread.h
class MyThread : public QThread { // Assuming you're inheriting from QThread
public:
// instead of setting it via the ctor, you could consider adding a setter
MyThread(MyObjectClass *moc) : moc_(moc) {}
void run();
private:
MyThread(); // explicitly stating that the default ctor cant be called
MyObjecctClass *moc_
};
anyThread.cpp
void MyThread::run()
{
moc_->GetSome(); //This should work
// Dont have to worry about the setters, since there are none
// available for the MyObjectClass, which is now immutable
}