Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 崩溃,施工前使用它_C++ - Fatal编程技术网

C++ 崩溃,施工前使用它

C++ 崩溃,施工前使用它,c++,C++,我有一个类,它的对象将被另一个类使用,如下所示 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应用程序。我在主窗口下有一个窗口,显示当前操作的一些基本信息,例如正

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

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)后删除了窗口造成的。然后,我将窗口的引用指针放在singleton中。当构建窗口时,我设置了引用指针。窗口的删除由主窗口控制。从而解决了上述碰撞问题。但是如果其他开发人员在构建窗口之前使用单例,代码也会崩溃。有什么好办法解决吗?或者我们可以接受它,因为在构建之前使用它是开发人员的错误?非常感谢

您必须使用初始化
m_a
而不是分配它。
它确保您在调用其他函数之前不必费心分配
ma

您必须使用来初始化
ma
,而不是分配它。 它确保您在调用其他函数之前不必费心分配
ma

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

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;

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

#包括
B类
{
公众:
布尔G()
{ 
如果(m_a==nullptr)返回false;//没有未定义的行为!
m_a->F();//此调用现在是安全的
...
返回true;
}
私人:
std::shared_ptr m_a;//自动初始化为null ptr
};
如果未初始化
m_a
,调用函数
G()
可能会导致未定义的行为,因此您需要确保情况并非如此。您必须更改代码,使其看起来有点像这样:

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;

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

#包括
B类
{
公众:
布尔G()
{ 
如果(m_a==nullptr)返回false;//没有未定义的行为!
m_a->F();//此调用现在是安全的
...
返回true;
}
私人:
std::shared_ptr m_a;//自动初始化为null ptr
};

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

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

并确保在所有构造函数中初始化
m_a
,如果当前没有真正的
a
指向,则至少初始化为空指针。

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

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

并确保在所有构造函数中初始化
ma
,如果您当前没有真正的
a
指向,则至少初始化为空指针。

这取决于您在文档中编写的内容!它怎么可能是一个可接受的设计?调用
G()
是未定义的行为。也许我不明白这取决于你在文档中写了什么!它怎么可能是一个可接受的设计?调用
G()
是未定义的行为。也许我不明白it@OliCharlesworth:是的,但是如果OP担心参与者调用函数的顺序,那么只有两种方法:1。将其记录在接口文档或2中。在构造过程中初始化指针成员。@OliCharlesworth:是的,但是如果OP担心参与者调用函数的顺序,那么只有两种方法:1。将其记录在接口文档或2中。在构造期间初始化指针成员。问题语句中没有足够的信息来证明“您应该使用智能指针…”。也许“你应该考虑使用智能指针……”PeteBecker:我知道你的意思,但即使是智能指针将自己初始化为<代码> NulLPTR < /代码>的事实,而原始指针不需要手动初始化,在本例中也有直接的好处。此外,在现代C++中,必须有一个好的理由不使用智能指针,以便更喜欢原始指针。虽然这些情况确实存在,但我认为它们并不代表默认情况。如果这个例子没有提到选择原始指针的好理由,我觉得有资格提到应该使用智能指针。因此我的措辞。为了不必初始化某些东西而更改所有权语义是由内而外的设计。@PeteBecker:我的措辞是“智能指针”,包括
弱\u ptr
唯一\u ptr
,和
共享\u ptr
。我坚持我的观点:“你应该使用智能指针”。除非有充分的理由。当然,我们应该选择实现适当所有权语义的智能指针。我的最后一个例子只是选择了一个,我认为没有havin,信息就足够清晰了