【问题标题】:Object doesn't get constructed [closed]对象没有被构造[关闭]
【发布时间】:2013-01-09 21:58:52
【问题描述】:

我注意到这种奇怪的行为/错误,其中在实际对象初始化之前 调用了类方法。我有一个包装对象,它有operator->() 方法。现在,当我使用 operator->() 方法将对象作为构造函数中的构造函数参数传递给另一个对象时,不会构造实际的包装器对象,而只是运行 operator->() 方法。

由于实际的代码示例非常复杂并且依赖于许多其他的东西,我将只展示可能无法正确编译的 C++ 代码 sn-p:

template<typename T>
class wrapper_object_type
{
public:
    wrapper_object_type() {/*does not run*/}
    T* operator->() {/*does run*/}
};
class bad_behaviour
{
public:
    bad_behaviour() : another_object(wrapper_object->t_object) 
    {/*crashes(0xccc access violation*/}
};

那么标准中是否有定义允许这种行为的东西?或者更准确地说,是否有一些隐式构造等可以绕过默认构造?

【问题讨论】:

  • 您的代码 sn-p 相当荒谬。
  • wrapper_objectbad_behaviour 构造函数中来自哪里?
  • wrapper_objectbad_behaviour 类中,wrapper_object_type 类有一个 T 类型的静态实例。 wrapper_object_type 类充当共享实例,与boost::shared_from_this 非常相似
  • @weggo another_objectwrapper_objectbad_behavior 类中声明的顺序是什么?如果首先声明another_object,那么我不相信wrapper_object 的构造函数会被执行,如果它是一个对象的话。如果wrapper_object 是指针类型,那么您只是在处理wrapper_object 尚未初始化的事实。
  • 您的问题不是独立的。您提供的代码无法编译,您的问题存在于您未提供的代码中。请提供一个实际编译的示例:sscce.org

标签: c++ object operator-overloading construction


【解决方案1】:

您可能在初始化之前使用wrapper_object。成员变量的构造顺序与它们在类中的声明顺序相同,因此请确保 wrapper_objectanother_object 之前声明。

(假设wrapper_objectanother_objectbad_behaviour的成员变量,但没有更合理的代码示例很难说。)

【讨论】:

  • wrapper_object 应该被初始化,因为-&gt; 只是对重载运算符的调用。根据我对 C++ 的理解,该对象至少是在使用成员函数之前隐式构造的。 (在调用成员函数之前,我确实尝试过显式构造它)
  • @weggo 所有的对象至少在进入constructor之前被构造,但不是initializer list。您正在使用初始化器列表中的成员,因此您必须确保您正在使用的成员在您正在初始化的成员之前声明,否则编译器将为使用的成员发出构造代码你尝试使用它之后。
【解决方案2】:

好吧,我确实做到了;我将对象从堆栈切换到堆,并通过 new 关键字而不是在初始化列表中显式初始化它们。正如我所想,这并没有重现奇怪的行为,所以它按预期工作。我现在在想的是,它实际上可能是一个编译器错误,因为我通过初始化列表执行此操作的方式类似于我解决问题的方式。唯一改变的是我之前没有在堆中分配它们。

我还尝试提供重现该错误的工作代码,但该错误未显示在那里。这可能是因为发现错误的实际代码在很大程度上依赖于模板类型和包装对象。当对象在堆中分配时,它现在可以工作,错误不在代码中,而是在编译器中。

【讨论】:

    猜你喜欢
    • 2022-06-13
    • 2013-05-23
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 2021-12-07
    • 2015-10-11
    相关资源
    最近更新 更多