C++ 使用基类调用新的布局

C++ 使用基类调用新的布局,c++,new-operator,c++17,C++,New Operator,C++17,我对新的位置有疑问。我想在类派生方法中调用基类构造函数。代码应该更清楚地说明这一点 代码 #包括 #包括 #包括 #包括 双计算z(整数x){ 返回2*x; } 结构基{ int x; 双z; Base():x(0),z(0){} 基(int值):x(值),z(计算_z(x)){ }; 派生类:公共基{ 公众: //这足以保证安全吗? 静态断言(std::is_平凡的_可复制的::value,“使用新的in-placement构造函数的对象必须平凡!”); std:可选力; 空荷载(整数x) {

我对新的位置有疑问。我想在类派生方法中调用基类构造函数。代码应该更清楚地说明这一点

代码
#包括
#包括
#包括
#包括
双计算z(整数x){
返回2*x;
}
结构基{
int x;
双z;
Base():x(0),z(0){}
基(int值):x(值),z(计算_z(x)){
};
派生类:公共基{
公众:
//这足以保证安全吗?
静态断言(std::is_平凡的_可复制的::value,“使用新的in-placement构造函数的对象必须平凡!”);
std:可选力;
空荷载(整数x)
{
新(这个)基地(x);//我能称之为安全基地吗?这会给部队成员带来麻烦吗?
//我需要手动调用析构函数还是delate?(可能不需要)
强制=标准::使_可选(假);
}
};
int main()
{
导出了一个;
a、 载荷(5);
}

理由 这个例子看起来毫无意义。但该类中的基类不是
T
。衍生工具是
模板
。我需要调用这个构造函数,因为我从JSON读取数据。我使用的序列化库要求已经存在该对象。不从Base继承是一个问题(因为我可以使用Base作为成员)。那么为什么我需要调用构造函数呢?因为T来自其他库,并且没有调用构造函数,所以我的应用程序无法正常工作

所以问题:

  • 我的程序安全吗
  • 如果1为“是”,则一个特征是否足以用模板替换基
  • 如果没有,我怎样才能保证安全
  • 作为成员的基础
    我无法将Base作为成员,因为我使用

    将其序列化,您想在这里写什么?在你列出的链接中,没有任何地方会有这样的建议

    看起来你想要的是:

    struct Base {
        int x;
        double z;
    
        Base(): x(0), z(0) {}
        Base(int value): x(value), z( calculate_z(x) ) {}
    };
    
    class Derived : public Base {
        std::optional<bool> force; 
    
        template<class Archive>
        void serialize(Archive & archive)
        {
            archive( x, z, force );
        }
    };
    
    class Safer {
        Base b;
        std::optional<bool> force; 
    
        template<class Archive>
        void serialize(Archive & archive)
        {
            archive( b.x, b.z, force );
        }
    };
    
    class Constructs {
        Base b;
        std::optional<bool> force; 
    
        template<class Archive>
        void load(Archive & archive)
        {
            int x, z;
            archive( x, z, force );
            b = Base( x );
            // Could be
            // b = Base( x, z );
        }
    
        template<class Archive>
        void save(Archive & archive)
        {
            archive( b.x, b.z/*???*/, force );
        }
    };
    
    struct Base{
    int x;
    双z;
    Base():x(0),z(0){}
    基(int值):x(值),z(计算_z(x)){
    };
    派生类:公共基{
    std:可选力;
    模板
    作废序列化(存档和存档)
    {
    档案(x、z、力);
    }
    };
    班级安全{
    碱基b;
    std:可选力;
    模板
    作废序列化(存档和存档)
    {
    档案(b.x、b.z、force);
    }
    };
    类构造{
    碱基b;
    std:可选力;
    模板
    无效加载(存档和存档)
    {
    int x,z;
    档案(x、z、力);
    b=基准(x);
    //可能是
    //b=基底(x,z);
    }
    模板
    作废保存(存档和存档)
    {
    档案(b.x,b.z/*?*/,强制);
    }
    };
    
    首先将此转换为
    Base*
    ,然后转换为
    void*
    ,以确保传递给placement new的地址正确无误。那么它将是合法的,尽管有疑问(而且可能很脆弱)。就个人而言,我会做一些类似于
    static_cast(*this)=Base{x}。我不知道有哪个编译器不能正确地优化它。我不明白为什么需要从
    Base
    继承。您在哪里使用
    Derived
    作为
    Base
    ,您不能只使用一个成员
    Base
    ?或者一个成员
    std::optional
    ,所以您可以延迟构建,直到所有未定义行为的风险消失。我越是阅读您的注释和用例,我越是相信派生是错误的。您想要继承一个第三方类(当您决定更新它时,或者如果他们没有虚拟析构函数,那么这可能会有风险);您希望它只处理序列化,然后创建一个
    基本加载(intx)
    函数。虽然我认为你所做的事可能是安全的,以你为例;当静态断言失败时(可能是第三方代码!)你会怎么做?我要补充的是,静态断言没有失败的任何基础都严重限制了继承优于组合的好处。不!!这将导致创建不正确的JSON:(这更复杂。如果你想帮忙,请帮我解答
    new
    问题。你似乎很确定,但没有人知道。你能举个例子说明这是怎么回事吗?你试过这种方法吗?你不能在这里安全地使用placement
    new
    。当你这样做时,你不再有
    派生的
    。@S.R
    我已经试过你了以会员身份唱这首歌
    ,因为你自己承认它应该是会员;我建议你回去问一个关于它不起作用的问题。我不同意没有人回答你的问题,但是(对我来说)这是因为它不仅不能解决您的问题,而且可能会导致您采取一些非常糟糕的做法。旁白:不要继承缺少虚拟析构函数的库类。您无法知道是否存在
    Base*ptr=…;delete ptr;
    struct Base {
        int x;
        double z;
    
        Base(): x(0), z(0) {}
        Base(int value): x(value), z( calculate_z(x) ) {}
    };
    
    class Derived : public Base {
        std::optional<bool> force; 
    
        template<class Archive>
        void serialize(Archive & archive)
        {
            archive( x, z, force );
        }
    };
    
    class Safer {
        Base b;
        std::optional<bool> force; 
    
        template<class Archive>
        void serialize(Archive & archive)
        {
            archive( b.x, b.z, force );
        }
    };
    
    class Constructs {
        Base b;
        std::optional<bool> force; 
    
        template<class Archive>
        void load(Archive & archive)
        {
            int x, z;
            archive( x, z, force );
            b = Base( x );
            // Could be
            // b = Base( x, z );
        }
    
        template<class Archive>
        void save(Archive & archive)
        {
            archive( b.x, b.z/*???*/, force );
        }
    };