1

我有一个类,它的对象将被另一个类使用,如下所示

class A
{
public:
    void F() {...}
};

class B
{
public:
    void G() { m_a->F(); ...} // use A's function

private:
    A* m_a;
};

因此在分配指针 m_a 之前调用 B::G() 是错误的。这是可接受的设计吗?或者有更好的方法来做到这一点。

问题来自开发 GUI 应用程序。我在主窗口下面有一个窗口,用来显示当前操作的一些基本信息,比如发生了什么,需要多长时间等等。我把这个窗口作为一个单独的窗口,以便通过可能分散在任何地方的操作轻松访问,并在关闭 GUI 应用程序时发现代码崩溃。崩溃是由于删除GUI应用程序(如Qt中的qApp)后删除了窗口。然后我只是将窗口的引用指针放在单例中。并且在构建窗口时,我设置了引用指针。窗口的删除由主窗口控制。这样就解决了上面提到的崩溃问题。但是如果其他开发人员在窗口构建之前使用单例,代码也会崩溃。有什么好办法解决吗?或者我们可以接受它,因为在构建之前使用它是开发人员的错误?非常感谢!

4

3 回答 3

3

如果未初始化,调用函数G()可能会导致未定义的行为m_a,因此您要确保不会出现这种情况。您必须更改代码以使其看起来像这样:

class B
{

public:

    B() : m_a(nullptr) { } // m_a always initialized!

    bool G() 
    { 
        if (m_a == nullptr) return false; // No Undefined Behavior!
        m_a->F(); // This call is safe now
        ...
        return true;
    }

private:

    A* m_a;

};

顺便说一句,通常您应该使用智能指针(选择实现适当所有权语义的类型)而不是原始指针,除非您有充分的理由这样做。这甚至可以使您免于手动初始化(假设此处共享所有权):

#include <memory>

class B
{

public:

    bool G() 
    { 
        if (m_a == nullptr) return false; // No Undefined Behavior!
        m_a->F(); // This call is safe now
        ...
        return true;
    }

private:

    std::shared_ptr<A> m_a; // Automatically initalized to nullptr

};
于 2013-01-31T15:52:53.450 回答
2

您必须使用成员初始化器列表初始化 m_a而不是分配它。m_a它确保您在调用其他函数之前不必担心被分配。

于 2013-01-31T15:47:35.723 回答
1

根据您对类的预期用法,这可能是一种可接受的做法,但如果您这样做,您最好B::G()先更改为检查指针:

void G() { if (m_a) m_a->F(); ...}

并确保m_a在所有构造函数中进行初始化,如果您当前没有实数指向,则至少初始化为空指针A

于 2013-01-31T15:53:36.990 回答