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来自其他库,并且没有调用构造函数,所以我的应用程序无法正常工作
所以问题:
我无法将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
问题。你似乎很确定,但没有人知道。你能举个例子说明这是怎么回事吗?你试过这种方法吗?你不能在这里安全地使用placementnew
。当你这样做时,你不再有派生的
。@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 );
}
};