2

我正在用 QT 编写一个 c++ 应用程序,重点是速度优化。我想要一些对不同线程具有只读访问权限的全局对象。在打开线程之前,我必须初始化全局对象并用数据填充它们。

如何保护我的全局对象的设置功能,但仍然可以从主功能访问?

像现在这样的示例代码:

我的类.h

class MyObjectClass {
public:
void SetSome(const QList<QString> &value);
QList<QString> GetSome() const;

private:
    QList<QString> m_myMember;
};

主文件

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

任何线程.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
}

如果您有一些设计想法给我,我会很高兴,非常感谢!

4

3 回答 3

0

制作您的全局变量static,这意味着只有一个源文件可以访问它。然后,您可以提供可以从其他线程读取数据的访问器函数。

于 2012-10-30T17:08:07.693 回答
0

对于初学者,我会不惜一切代价避免使用全局变量。

除了全局变量之外,您可以做的是在 main 中实例化一个变量(动态地或在堆栈上本地,取决于您的偏好)并将其设置在线程对象中(这称为dependency injection

要仅从 main 控制 MyObjectClass 上的设置属性,我可以想到 2 个选项:

  1. 通过 main 中的构造函数设置所有 MyObjectClass 属性,从而允许您删除 setter,但保留 getter。MyObjectClass 将是不可变的。

  2. 创建一个包含 MyObjectClass 的所有可设置属性的上下文对象。此上下文对象只能传递给 MyObjectClass 构造函数。上下文对象应该在 main 中创建,调用适当的设置器,然后在从 main 实例化时传递到 MyObjectClass。MyObjectClass 类在内部使用上下文对象的这些属性,但没有它们的设置器。MyObjectClass 上当然会有可用的 getter,它会从内部上下文对象中获取值。MyObjectClass 将是不可变的,但这种方式更灵活一些。

我更喜欢第二种选择。这是一个代码示例:

我的类.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
};

主文件

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

任何线程.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_
};

任何线程.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
}
于 2012-10-30T18:10:37.393 回答
0
class MyPrivateObjectClass : private MyObjectClass
{
public:
   friend void main();
};

extern MyPrivateObjectClass g_InitializedInMain;
于 2012-10-30T17:00:49.903 回答