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!
}