指针强制转换期间的初始化
Initialization during a pointer cast?
如果我定义了一个派生类,它有初始化器,但最终使用指针强制转换(即static_pointer_cast),那么我如何在不执行解引用和对象复制的情况下执行初始化器?
#include <string>
#include <memory>
class Base {
public:
std::string Name;
};
class Derived : public Base {
public:
std::string Address = "Initialized";
};
int main() {
auto b_ptr = std::make_shared<Base>();
b_ptr->Name = "Fred";
auto d_ptr = std::static_pointer_cast<Derived>(b_ptr);
fprintf( stdout, "Name: [%s] Address: [%s]",
d_ptr->Name.c_str(),
d_ptr->Address.c_str() ); // Address not valid!
}
链接到代码:http://coliru.stacked-crooked.com/a/09f2240abff1556b
处理这个问题的正确方法是什么?
编辑:下面是一些示例代码(当然,比真实的代码简化了很多),它更好地说明了我正在尝试做什么,以及为什么如果有一种方法可以让它发挥作用会很好。
更新的样本代码:http://coliru.stacked-crooked.com/a/cdcc31a4417bb52b
在本例中,我有两个数据源,一个来自源系统,另一个来自内部使用的数据源。我真的不想复制所有的数据,只是在上面叠加一些额外的信息
我不确定是否要使用std::move(正如@MooingDuck所建议的),因为它会对源数据产生影响。。。。我需要更多地探索。但是从这个例子中,不执行复制的好处是显而易见的,并且必须使用"has-a"风格的实现会使后续的对象使用变得尴尬。即:
test_row->Values[0].c_str() and
test_row->RowTotal
将变成:
test_row->row->Values[0] yet still
test_row->RowTotal
也许我认为这一切都错了,有更好的算法可以做到这一点吗?
您可以给Derived
一个Base&&
构造函数,并使用它将Base
的内容移动(浅拷贝)到派生中,从而使原始Base
处于"空"状态。
class Base {
public:
std::string Name;
//Note: The compiler is generating these invisibly for you:
//Base() :Name() {}
//~Base() {}
//Base(const Base& r) : Name(r.Name) {}
//Base(Base&& r) noexcept : Name(std::move(r.Name)) {}
//Base& operator=(const Base& r) : Name(r.Name) {}
//Base& operator=(Base&& r) noexcept : Name(std::move(r.Name)) {}
};
class Derived : public Base {
public:
std::string Address = "Initialized";
Derived() = default;
Derived(Base&& b) : Base(std::move(b)) {}
};
int main() {
auto b_ptr = std::make_shared<Base>();
b_ptr->Name = "Fred";
auto d_ptr = std::make_shared<Derived>(std::move(*b_ptr));
//NOTE AT THIS POINT b_ptr POINTS TO A BASE WHOS Name IS EMPTY
b_ptr.reset(); //reset to prevent accidental errors with lack of content
fprintf( stdout, "Name: [%s] Address: [%s]",
d_ptr->Name.c_str(),
d_ptr->Address.c_str() ); // Address not valid!
}
请在此处查看它的工作情况:http://coliru.stacked-crooked.com/a/f3a6062f6c459c7c
还可以在此处查看运动证明:http://coliru.stacked-crooked.com/a/f7f6cc4aa06d2746
然而,值得注意的是,我想不出有什么好的理由让你想这么做。听起来你的代码设计得很糟糕。
你不能。成员的大括号或相等的初始值设定项仅由构造函数执行。如果要初始化Derived::Address
,则需要实际构造一个Derived
对象。但是,不能在Base
对象已经占用的空间上构造Derived
对象;您必须首先销毁Base
对象。
您无法就地更改类型。不要进行额外的初始化,也不要礼貌地询问。这是不可能的。
如果你问自己,这很容易看出
make_shared<Base>
分配了多少内存?
- 复制列表初始化的隐式转换的等级是多少
- C++转换参数初始化问题
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 是否可以将已经初始化的变量转换为 void*?
- C++列表初始化允许多个用户定义的转换
- 为什么 gcc 警告只针对统一初始化缩小转换范围?
- 无法在初始化时将"日期"转换为"int"作为错误
- 常量转发引用给出错误 C2440:"正在初始化":无法从"常量标准::字符串"转换为"常量标准::字符串 &&"
- 统一初始化是隐式发生的,即使 int 强制转换运算符是使用 explicit 关键字声明的.原因是什么?
- 使用转换函数直接初始化
- 正在初始化:无法从'_Ty*'转换为 List<int,std::分配器<节点<T>>>:节点*
- 警告 C4267"正在初始化":从'size_t'转换为"DWORD",可能会丢失数据
- 通过用户定义的转换初始化引用
- 在C++中初始化bool32_t对象时,我们需要强制转换它还是它会自动识别它?
- 复制初始化 - 从 'int' 类型转换为非标量类型
- 用于初始化结构的 void 指针强制转换
- 错误 C2440:"正在初始化":无法从"初始值设定项列表"转换为"std::vector<char *,std::分配器<_Ty>>
- 如何将模板大小的数组初始化转换为 constexpr 初始化