C++ 将子结构值设置为纯虚函数返回的值在对象构造函数中是否安全?

C++ 将子结构值设置为纯虚函数返回的值在对象构造函数中是否安全?,c++,virtual-functions,C++,Virtual Functions,考虑(注意从对象中删除的一些代码,即构造函数/析构函数和一些变量): 及 请注意初始化\u属性的用法 这样安全吗?如果我手动内联初始化\u属性,clang会拒绝编译它,因为它在构造函数中调用纯虚函数 有没有比我现在做的更好的初始化属性的方法 不,这不安全 我将对代码进行折射,这样用户就有必要调用一个成员函数来执行初始化。它不像我希望的那样自动,但可能是最好的。简短回答:不要这样做 说明: 构造对象时,对象的类型为对象,而不是派生类。让我们调用派生类my\u对象 在对象的构造函数中调用对象版本的任

考虑(注意从
对象
中删除的一些代码,即构造函数/析构函数和一些变量):

请注意
初始化\u属性的用法

  • 这样安全吗?如果我手动内联
    初始化\u属性
    ,clang会拒绝编译它,因为它在构造函数中调用纯虚函数
  • 有没有比我现在做的更好的初始化
    属性的方法
  • 不,这不安全


    我将对代码进行折射,这样用户就有必要调用一个成员函数来执行初始化。它不像我希望的那样自动,但可能是最好的。

    简短回答:不要这样做

    说明: 构造
    对象
    时,对象的类型为
    对象
    ,而不是派生类。让我们调用派生类
    my\u对象

    在对象的构造函数中调用对象版本的任何虚拟函数(纯函数或非纯函数)。 仅在
    my\u object::my\u object()
    的主体中,对象类型是
    my\u object
    ,而不是之前

    解决方案是将构造与初始化分离。 从
    my_object::my_object()
    调用虚拟函数Initialize或更好的方法,将其公开为公共方法,以便创建my_object实例的代码将调用它来初始化对象

    例如:

    my_object o;
    o.Init(params);
    

    很好。但是为什么
    initialize_属性
    应该是
    inline
    ?这是一个常见的实现细节——将其保存在翻译单元中。无论如何,架构有点笨拙,需要重新设计。如果不知道你想要实现什么,不知道例子,不知道为什么你需要这些额外的
    bool
    成员,就很难给出答案。实际上,从我在线程中读到的,这是不安全的。哈罗根:它们是可变的,只在构造时设置为该类对象的“默认”值。哦,你也在构造函数中调用它们-是的,你最好不要这样做。重新设计的另一个原因。不,在构造函数中调用纯虚拟函数总是一个bug(它会崩溃),而在构造函数中调用非纯虚拟函数几乎总是一个bug(它不会做大多数新手期望它做的事情)。如果使用CRTP,可能可以让事情自动进行。考虑这个代码:<代码>模板类基数{…};类Myclass:公共基{…}
    Now
    Base
    可以整天调用
    派生的
    静态函数,即使在构造函数中也是如此。基类的不同类型有点达不到目标。
    Base
    的各种变体没有任何关联-不能在列表、数组等中一起使用。“解决方案是将构造与初始化分离”:一种可能的解决方案是。。。(例如,n.m.在下面的注释中建议另一个(即CRTP)调用静态函数是非常有限的,并且CRTP更复杂(代码可读性较差)。在这种情况下,期望的结果是单个基类。如果基类使用模板,则不能与模板的其他变体一起使用,因为它们是完全不同的类:
    base
    base
    没有共同点-例如,不能放在单个容器中。
      object::object(unsigned long id, real_t x, real_t y)
        : id(id), xstart(x), ystart(y), x(x), y(y), xprevious(x), yprevious(y), properties{} {
        this->initialize_properties(this->properties);
      }
    
      void object::initialize_properties(object::object_properties& prop) {
        prop.solid = this->object_is_solid();
        prop.visible = this->object_is_visible();
        prop.persistent = this->object_is_persistent();
        prop.depth = this->object_depth();
        prop.sprite_index = this->object_sprite_index();
        prop.mask_index = this->object_mask_index();
        prop.image_alpha = 1;
        prop.image_speed = 1;
        prop.image_xscale = 1;
        prop.image_yscale = 1;
      }
    
    my_object o;
    o.Init(params);