c++ - 在指针转换期间初始化?

标签 c++ c++11 derived

如果我定义了一个具有初始化器的派生类,但最终使用指针转换(即 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(如@Mooing Duck 所建议的那样),因为它对源数据有影响……我需要进一步探索。但是从这个例子来看,不执行复制的好处是显而易见的,必须使用“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 的内容移动(浅拷贝)到 derived ,这使原始 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

但是,值得注意的是,我想不出您想要这样做的充分理由。听起来您的代码设计不佳。

关于c++ - 在指针转换期间初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28729768/

相关文章:

c++ - C++ 中结构函数头中的声明(简单)

单元的 C++ 可用 "literal suffix code"

c++ - 带有基类的模板类

c++ - 平均循环,for 循环不执行

c++ - getline() 与 ifstream 的意外行为

c++ - 这个打印代码是如何工作的?

c++ - 无法调用 std::function

C++:我可以编写一个从 T 派生的模板类吗?

c# - 派生类列表上的泛型函数

c++ - C++ 中的指针和引用错误