5

也许我试图过于笼统。(下面的原始问题)具体来说,我对Depclass有一些依赖Foo。我也有一个类MockDep,并且正在定义一个类TestFoo。这是我尝试编写的构造函数:

TestFoo(unique_ptr<MockDep> dep) : Foo(std::move(dep)), mock_dep_(dep.get()) {}

AndFoo的构造函数看起来像:

Foo(unique_ptr<Dep> dep) : dep_(dep) {}

mock_dep_TestFooas中声明MockDep* mock_dep_,并在as中声明。我怎样才能得到包含的地址?(因为上面的内容无效,因为nulls out 。)dep_Foounique_ptr<Dep> dep_mock_dep_dep_std::move(dep)dep


原帖:

我有一个类型的对象Foo,我要传递给另一个OtherObject声称拥有它的类型的对象,但作为指向它的基类的指针。但是,我想获取一个指向可以用来引用它的子对象的指针。我写了类似的东西:

Foo(std::unique_ptr<Child> thing) :
    OtherObject(std::move(thing)), child_(thing.get()) {}

OtherObject(std::unique_ptr<Base> thing, ...) { ... }

但是,这似乎不起作用,因为似乎使稍后std::move(thing)返回的指针无效。thing.get()

我可以将Foo' 参数更改为 typeChild*而不是unique_ptr<Child>,但我更希望能够执行后者,因为它明确记录了所有权语义。

解决这个问题的最合适(或失败,不引人注目)的方法是什么?

编辑Foo并且OtherObject都意味着我正在定义其构造函数的类。

4

2 回答 2

6

您可以使用:

Foo(std::unique_ptr<Child> thing) :
    OtherObject(std::move(thing)),
    child_(OtherObject.getChildPtr()) /* one accessor to get the pointer. */
{}

如果基础对象OtherObject不提供指针的访问器,您可以将构造函数委托给其他构造函数,例如:

class Foo: public OtherObject
{
public:
    Foo(std::unique_ptr<Child> thing) : Foo(thing, thing.get()) {}

private:
    Foo(std::unique_ptr<Child>& thing, Child* child) :
        OtherObject(std::move(thing)),
        child_(child)
    {}
private:
    Child* child_;
};

第三种解决方案是通过引入另一个推导来改变 and 之间的顺序(之前OtherObjectchild_) :child_

class ChildPtr
{
public:
    ChildPtr(Child* child) : child_(child) {}

    Child* child_;
};

class Foo: private ChildPtr, public OtherObject
{
public:
    Foo(std::unique_ptr<Child> thing) :
        ChildPtr(thing.get()),
        OtherObject(std::move(thing))
    {}
};
于 2014-06-09T23:06:43.023 回答
1

通常,标准中将发生的情况描述为:

§17.6.5.15.1库类型的移动状态[lib.types.movedfrom]

C++ 标准库中定义的类型的对象可以从 (12.8) 中移出。移动操作可以显式指定或隐式生成。除非另有说明,否则此类移出的对象应置于有效但未指定的状态。

该标准实际上具体描述了std::unique_ptrin 的行为:

§20.8.1.4类模板 unique_ptr [unique.ptr]

此外,u可以根据要求将所有权转移到另一个唯一指针u2。完成此类转让后,以下后置条件成立:

  • u2.p等于pre-transfer up,
  • up 等于 nullptr,并且
  • 如果pre-transfer ud保持状态,则该状态已经转移到u2.d。

具体来说,dep在构建Foo子对象后:

Foo(std::move(dep))

是一个nullptr

此外,如果dep仍然是一个有效的指针,Foo(std::move(dep))就会复制dep,这对于 ' 的语义没有意义std::unique_ptr(因为它是不可复制的)。

您想要做的是在适当考虑案例的情况下引用指向的对象(例如,unique_ptr 可以是nullpt?等),在Foo

class Foo {
public:
    Foo(unique_ptr<Dep> dep) : dep_(dep) {}
    const Dep& get_dep() const { return *dep_; }
    Dep& get_dep()             { return *dep_; }
private:
    std::unique_ptr<Dep> dep_;
};

然后简单地将TestFoo对象构造为:

TestFoo(unique_ptr<MockDep> dep) : Foo(std::move(dep)) {}
于 2014-06-09T23:32:43.950 回答