关于PIMPL语法

发布于 2025-01-27 13:42:48 字数 669 浏览 3 评论 0原文

我对PIMPL语法中使用的C ++使用情况有疑问。

首先,为什么不需要编写pimpl(new Impl)pimpl(new my_class :: :: inprand)

第二,为什么new new Impl < /代码>扩展即使是临时对象?

//my_class.h
class my_class {
   //  ... all public and protected stuff goes here ...
private:
   class impl; unique_ptr<impl> pimpl; // opaque type here
}
// my_class.cpp
class my_class::impl {  // defined privately here
  // ... all private data and functions: all of these
  //     can now change without recompiling callers ...
};
my_class::my_class(): pimpl( new impl )
{
  // ... set impl values ...
}

I have a question about the C++ usage used in the pimpl syntax.

First, why is it not necessary to write pimpl( new impl ) as pimpl( new my_class::impl )

Second, why is the lifetime of new impl extended even though it is a temporary object?

//my_class.h
class my_class {
   //  ... all public and protected stuff goes here ...
private:
   class impl; unique_ptr<impl> pimpl; // opaque type here
}
// my_class.cpp
class my_class::impl {  // defined privately here
  // ... all private data and functions: all of these
  //     can now change without recompiling callers ...
};
my_class::my_class(): pimpl( new impl )
{
  // ... set impl values ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鸩远一方 2025-02-03 13:42:48

首先:在您的构造函数中表达式新的imph 确实是一个临时对象,但是立即将其传递给pimpl成员,这不是临时。 std :: unique_ptr类型存储指针传递给它,并将其保留在其上,直到被破坏或移动为止。直到my_class对象被破坏之前,成员不会被破坏。

另外,考虑使用 std :: make_unique 而不是new

第二:您不必写my_class :: impl因为您处于my_class的成员函数,因此名称分辨率看起来看起来不仅在命名空间范围内,而且在类范围范围内。因此,impl可以解决。

First: In your constructor the expression new impl indeed is a temporary object, but it is immediately passed to the pimpl member which is not a temporary. The std::unique_ptr type stores the pointer passed to it and holds on to it until it is destroyed or moved. And the member is not destroyed until the my_class object is destroyed.

Also, consider using std::make_unique instead of new.

Second: You don't have to write my_class::impl because you are in a member function of my_class, so name resolution looks not only at namespace scope but also at class scope. So, impl can be resolved.

陪你到最终 2025-02-03 13:42:48

首先,为什么不必将PIMPL(新IMP)写为PIMPL(新My_class :: inphand)

范围。当定义构造函数时,您在班级的范围内,因此 name lookup 能够毫无问题地找到它。

第二,为什么新impl的寿命即使是临时对象,也会扩展?

您将临时指针传递给std :: simolor_ptr&lt; nlpt&gt;的构造函数参数,因此值pimpl消耗了值。 impl值s不是临时的,因为它是在堆上创建的,对其寿命的控制传递给了智能指针。

额外:
您在标题中使用命名空间std; 使用(唯一可以跳过std ::之前simele_ptr之前的情况)!这是一个大错误,不要这样做。这将影响所有将包括此标头的所有来源。因此,您可能会有符号歧义错误。

即使在CPP文件中使用命名空间std; 使用也是考虑了不良练习

First, why is it not necessary to write pimpl( new impl ) as pimpl( new my_class::impl )

Scope. When constructor is defined you are inside a cope of a class, so name lookup is able to find it without problems.

Second, why is the lifetime of new impl extended even though it is a temporary object?

You are passing temporary pointer to as constructor argument of std::unique_ptr<impl> so value is consumed by a field pimpl. impl value s not temporary since it is created on a heap, control of its lifetime was passed to smart pointer.

Extra:
You did using namespace std; in header (the only case when you can skip std:: before unique_ptr)! This is BIG mistake do not do it. This will impact dangerously all sources which will include this header. You can have symbol ambiguity error because of that.

Even having using namespace std; in cpp file is considered a bad practice.

单身狗的梦 2025-02-03 13:42:48

新的Impl不是临时的,因为它不是变量。

这是一个表达式,

  1. 在您的my_class :: pimpl对象成员构建过程中进行评估,
  2. 其副作用是创建impl对象(其寿命是由控制的,而不是自动的,因为它不是本地自动变量),
  3. 并且它将指针返回到新创建的匿名 inpher对象。

该表达式用作pimpl成员my_class要构造的对象的初始化器,因此返回的指针作为初始化值传递给pimpl并存储在其中。这允许您的my_class对象控制impl对象的寿命。

pimpl指针变量的寿命显然与其拥有my_class对象的寿命相同,但是指向inpers> impl对象的寿命取决于您的my_class逻辑:

  1. 它可以将其保留到它自己的末端并在其自身破坏期间删除它,
  2. 它可以replace> replast()与另一个随意
  3. 或<代码> repares> pimpldelete impl对象,并且在不再需要的时候无需任何工作
  4. ...甚至释放对象, 将其删除,例如将所有权传输到另一个对象 - 或只是放弃它,这会导致内存泄漏(通常是一个严重的错误!)

The new impl is not temporary because it's not a variable.

It is an expression, which

  1. is evaluated during your my_class::pimpl object member construction,
  2. its side effect is creation of an impl object (whose lifetime is controlled, not automatic, because it's not a local automatic variable),
  3. and which returns a pointer to the newly created anonymous impl object.

The expression is used as an initializer to the pimpl member of the my_class object being constructed, so the returned pointer is passed as an initializing value to pimpl and gets stored in it. This allows your my_class object to control the life time of the impl object.

The life time of the pimpl pointer variable is obviously the same as its owning my_class object's life time, however the life time of the pointed impl object depends on your my_class logic:

  1. it may keep it until its own end and get it deleted during its own destruction,
  2. it may replace() it with another one at will
  3. or release() the pimpl, delete the impl object and work without any when no longer necessary...
  4. It might even release the object and not delete it, for example to transfer the ownership to another object – or just abandon it, which causes a memory leak (and which is usually a serious error!)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文