C++ 指针转换期间的初始化?
如果我定义了一个具有初始值设定项的派生类,但最终使用指针强制转换(即静态指针强制转换),那么如何在不执行取消引用和对象复制的情况下执行初始值设定项C++ 指针转换期间的初始化?,c++,c++11,derived,C++,C++11,Derived,如果我定义了一个具有初始值设定项的派生类,但最终使用指针强制转换(即静态指针强制转换),那么如何在不执行取消引用和对象复制的情况下执行初始值设定项 #include <string> #include <memory> class Base { public: std::string Name; }; class Derived : public Base { public: std::string Address = "Initialized"; }
#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!
}
将成为:
test_row->row->Values[0] yet still
test_row->RowTotal
也许我认为这一切都错了,有更好的算法来实现这一点吗?你不能。成员的大括号或相等初始值设定项仅由构造函数执行。如果要初始化
Derived::Address
,则需要实际构造一个Derived
对象。但是您不能在已被基本对象占用的空间上构造派生的对象;你必须先摧毁基地对象。你不能。成员的大括号或相等初始值设定项仅由构造函数执行。如果要初始化Derived::Address
,则需要实际构造一个Derived
对象。但是您不能在已被基本对象占用的空间上构造派生的对象;你必须先摧毁基地对象。你不能。成员的大括号或相等初始值设定项仅由构造函数执行。如果要初始化Derived::Address
,则需要实际构造一个Derived
对象。但是您不能在已被基本对象占用的空间上构造派生的对象;你必须先摧毁基地对象。你不能。成员的大括号或相等初始值设定项仅由构造函数执行。如果要初始化Derived::Address
,则需要实际构造一个Derived
对象。但是您不能在已被基本对象占用的空间上构造派生的对象;您必须先销毁基本对象。您不能在适当的位置更改类型。不是通过做额外的初始化,或者礼貌地询问。这是不可能的
如果你问自己,这很容易看出
make_shared
分配了多少内存
不能就地更改类型。不是通过做额外的初始化,或者礼貌地询问。这是不可能的
如果你问自己,这很容易看出
make_shared
分配了多少内存
不能就地更改类型。不是通过做额外的初始化,或者礼貌地询问。这是不可能的
如果你问自己,这很容易看出
make_shared
分配了多少内存
不能就地更改类型。不是通过做额外的初始化,或者礼貌地询问。这是不可能的
如果你问自己,这很容易看出
make_shared
分配了多少内存
您可以给Derived
一个Base&
构造函数,并使用它将Base
的内容移动(浅拷贝)到Derived中,从而使原始Base
处于“空”状态
类基{
公众:
std::字符串名;
//注意:编译器正在以不可见的方式为您生成以下内容:
//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)){}
};
派生类:公共基{
公众:
std::string Address=“已初始化”;
派生()=默认值;
派生(Base&&b):基(std::move(b)){}
};
int main(){
自动b_ptr=std::使_共享();
b_ptr->Name=“Fred”;
自动d_ptr=std::make_shared(std::move(*b_ptr));
//注:此时b_ptr指向一个名称为空的基
b_ptr.reset();//重置以防止因缺少内容而出现意外错误
fprintf(标准输出,“名称:[%s]地址:[%s]”,
d_ptr->Name.c_str(),
d_ptr->Address.c_str());//地址无效!
}
看到它在这里工作:
也可在此处查看运动证明:
然而,值得一提的是,我想不出一个好的理由让你想这么做。听起来你的代码设计得很糟糕。你可以给派生的一个基&&
构造函数,并用它将基
的内容移动(浅拷贝)到派生的中,这会使原始的基
处于“空”状态
类基{
公众:
std::字符串名;
//注意:编译器正在以不可见的方式为您生成以下内容:
//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)){}
};
派生类:公共基{
公众:
std::string Address=“已初始化”;
派生()=默认值;
派生(Base&&b):基(std::move(b)){}
};
int main(){
自动b_ptr=std::使_共享();
b_ptr->Name=“Fred”;
自动d_ptr=std::make_shared(std::move(*b_ptr));
//注:此时b_ptr指向一个名称为空的基
b_ptr.reset();//重置以防止因缺少内容而出现意外错误
fprintf(标准输出,“名称:[%s]地址:[%s]”,
d_ptr->Name.c_str(),
d_ptr->Address.c_str());//地址无效!
}
看到它在这里工作:
也可在此处查看运动证明:
然而,值得一提的是,我想不出一个好的理由让你想这么做。听起来你的代码设计得很糟糕。你可以给派生的一个基&&
构造函数,并用它将基
的内容移动(浅拷贝)到派生的中,这会使原始的基
处于“空”状态
类基{
P
test_row->row->Values[0] yet still
test_row->RowTotal
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!
}