Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C++中使用共享指针更容易的方法 我正忙着设计一个新的C++应用程序。在这个应用程序中,我希望用指针最小化潜在错误,并且由于应用程序应该是纯C++ NO.NET或其他新奇事物,所以我正在研究共享指针,我考虑到处使用共享指针而不是普通指针。_C++_Visual Studio 2010_C++11_Shared Ptr - Fatal编程技术网

在C++中使用共享指针更容易的方法 我正忙着设计一个新的C++应用程序。在这个应用程序中,我希望用指针最小化潜在错误,并且由于应用程序应该是纯C++ NO.NET或其他新奇事物,所以我正在研究共享指针,我考虑到处使用共享指针而不是普通指针。

在C++中使用共享指针更容易的方法 我正忙着设计一个新的C++应用程序。在这个应用程序中,我希望用指针最小化潜在错误,并且由于应用程序应该是纯C++ NO.NET或其他新奇事物,所以我正在研究共享指针,我考虑到处使用共享指针而不是普通指针。,c++,visual-studio-2010,c++11,shared-ptr,C++,Visual Studio 2010,C++11,Shared Ptr,我想出了一些技巧来简化共享指针的使用,例如:在类中使用typedef,如下所示: class X { public: ... typedef std::shared_ptr<X> Ptr; }; namespace boost { template< typename T > class shared_ptr; } namespace MyStuff { class Foo; class Bar; class

我想出了一些技巧来简化共享指针的使用,例如:在类中使用typedef,如下所示:

class X
   {
   public:
      ...
      typedef std::shared_ptr<X> Ptr;
   };
namespace boost { template< typename T > class shared_ptr; }

namespace MyStuff
{
   class Foo;
   class Bar;
   class Baz;

   typedef boost::shared_ptr<Foo> FooPtr;
   typedef boost::shared_ptr<Bar> BarPtr;
   typedef boost::shared_ptr<Baz> BazPtr;

}
通过这种方式,您可以轻松地编写X::Ptr,这比在任何地方编写std::shared_Ptr都要容易

我还注意到共享指针的一些缺点:

struct X;

...
std::shared_ptr<X> ptr;  // legal

struct X {};
ptr = std::shared_ptr<X>(new X); // legal
无论我在哪里使用我需要包含的共享指针 如果我只想使用指针,我就不能再使用前向声明了 有没有其他方法可以让共享指针更容易使用?

关于typedef,您应该看看哪些方法可以解决完全相同的问题

对于第二部分,我认为您错了,因为std::shared_ptr可用于N3225的20.9.10.2/2中规定的不完整类型:

shared_ptr的模板参数T 可能是不完整的类型

如果您当前的实现不支持这一点,我认为这应该被视为一个bug。

关于typedef,您应该看看哪些解决了完全相同的问题

对于第二部分,我认为您错了,因为std::shared_ptr可用于N3225的20.9.10.2/2中规定的不完整类型:

shared_ptr的模板参数T 可能是不完整的类型


如果您当前的实现不支持这一点,我认为这应该被视为一个bug。

不要只选择一个智能指针在任何地方使用。不是每个螺丝都是十字头

此外,您可以对任何智能指针使用与原始指针完全相同的正向声明:

struct X;

...
std::shared_ptr<X> ptr;  // legal

struct X {};
ptr = std::shared_ptr<X>(new X); // legal

这是我第二次在SO上听到这种误解,它完全是错误的。

不要只选择一个智能指针,在任何地方都可以使用。不是每个螺丝都是十字头

此外,您可以对任何智能指针使用与原始指针完全相同的正向声明:

struct X;

...
std::shared_ptr<X> ptr;  // legal

struct X {};
ptr = std::shared_ptr<X>(new X); // legal
这是我第二次听到这样的误解,它完全是错误的。

不要

最小化指针错误的唯一方法是使用正确的指针类型。这就是类型,复数

共享指针不是万能的。当你有周期性引用时,它们就会变成内存泄漏,如果你打算在任何地方都使用它们,那么它们很快就会出现

如果你想要无错误的C++应用程序,你必须为它工作。你必须了解你的申请。您必须理解不同对象的所有权语义。共享指针只提供共享所有权,这通常是一个合理的最低分母。其他的一切都可以被共享所有权所取代,它会起作用的

但默认情况下,一个对象由另一个实体拥有。它由一个函数拥有,并且应该在该函数返回时销毁,或者它由一个类或其他任何东西拥有。通常,您根本不需要指针。对象可能是通过std::vector中的值存储的。或者它只是一个局部变量或类成员。如果它是一个指针,通常最好用一个作用域\u ptr或一个允许所有权转移的唯一\u ptr或自动\u ptr来表示

当您无法保证对象的生存期或所有权时,您可能会求助于shared_ptr。但当你使用它时,你也需要使用弱ptr来打破循环

实际上,更好的方法是尽可能避免指针。当您确实需要一个指针时,请使用一个具有最具体的所有权语义的指针。首选作用域\u ptr,它根本不允许所有权转移,如果您需要它,请使用一个允许您移动所有权的指针,例如unique \u ptr,并且仅作为最后手段,您才应使用shared \u ptr,它允许您在任意数量的客户端之间自由共享所有权

没有任何魔杖可以让你的C++代码工作。实现这一点的唯一方法就是编写好的C++代码。你通过了解并使用你可以使用的工具来做到这一点,而不是假装嘿,shared_ptr就像一个垃圾收集器,不是吗?如果我使用它,我可以忽略所有关于对象生存期或内存泄漏的问题。

不要

最小化指针错误的唯一方法是使用正确的指针类型。这就是类型,复数

共享指针不是万能的。当你有周期性引用时,它们就会变成内存泄漏,如果你打算在任何地方都使用它们,那么它们很快就会出现

如果你想要无错误的C++应用程序,你必须为它工作。你必须了解你的申请。您必须理解不同对象的所有权语义。共享指针只提供共享的o 所有权,这通常是一个体面的最低分母。其他的一切都可以被共享所有权所取代,它会起作用的

但默认情况下,一个对象由另一个实体拥有。它由一个函数拥有,并且应该在该函数返回时销毁,或者它由一个类或其他任何东西拥有。通常,您根本不需要指针。对象可能是通过std::vector中的值存储的。或者它只是一个局部变量或类成员。如果它是一个指针,通常最好用一个作用域\u ptr或一个允许所有权转移的唯一\u ptr或自动\u ptr来表示

当您无法保证对象的生存期或所有权时,您可能会求助于shared_ptr。但当你使用它时,你也需要使用弱ptr来打破循环

实际上,更好的方法是尽可能避免指针。当您确实需要一个指针时,请使用一个具有最具体的所有权语义的指针。首选作用域\u ptr,它根本不允许所有权转移,如果您需要它,请使用一个允许您移动所有权的指针,例如unique \u ptr,并且仅作为最后手段,您才应使用shared \u ptr,它允许您在任意数量的客户端之间自由共享所有权


没有任何魔杖可以让你的C++代码工作。实现这一点的唯一方法就是编写好的C++代码。你通过了解并使用你可以使用的工具来做到这一点,而不是假装嘿,shared_ptr就像一个垃圾收集器,不是吗?如果我使用它,我可以忽略所有关于对象生存期或内存泄漏的问题。

在代码中,有一个约定是很常见的,然后您就可以遵循,只要在您的团队中一致地这样做,人们就能够理解它

在转发文件中声明共享指针typedef要好得多。大概是这样的:

class X
   {
   public:
      ...
      typedef std::shared_ptr<X> Ptr;
   };
namespace boost { template< typename T > class shared_ptr; }

namespace MyStuff
{
   class Foo;
   class Bar;
   class Baz;

   typedef boost::shared_ptr<Foo> FooPtr;
   typedef boost::shared_ptr<Bar> BarPtr;
   typedef boost::shared_ptr<Baz> BazPtr;

}
有时,您可能希望使用除shared_ptr之外的其他指针,但您的约定是使用不同的表示法,其中XPtr表示shared_ptr

当然,您可能会使用不同的表示法

我想我们用FooWeakPtr来表示弱 FooConstPtr是指共享的\u ptr

比如说


应该在您的编码标准文档中。

在代码中,有一个约定是很常见的,然后您就可以遵循这个约定,只要您的团队等一致地这样做,人们就能够理解它

在转发文件中声明共享指针typedef要好得多。大概是这样的:

class X
   {
   public:
      ...
      typedef std::shared_ptr<X> Ptr;
   };
namespace boost { template< typename T > class shared_ptr; }

namespace MyStuff
{
   class Foo;
   class Bar;
   class Baz;

   typedef boost::shared_ptr<Foo> FooPtr;
   typedef boost::shared_ptr<Bar> BarPtr;
   typedef boost::shared_ptr<Baz> BazPtr;

}
有时,您可能希望使用除shared_ptr之外的其他指针,但您的约定是使用不同的表示法,其中XPtr表示shared_ptr

当然,您可能会使用不同的表示法

我想我们用FooWeakPtr来表示弱 FooConstPtr是指共享的\u ptr

比如说


应该在您的编码标准文档中。

我更喜欢这种方法:

   namespace Internal
   {
      template <class T>
      struct DeclareShared
      {
         typedef std::shared_ptr<T> type;
      };

      template <class T>
      struct DeclareUnique
      {
         typedef std::unique_ptr<T> type;
      };
   }

   // Inherit one of these classes to use a generic smart pointer interface.

   // If class is abstract, use this interface.
   template <class T>
   struct SharedAbstract
   {
      typedef typename Internal::DeclareShared<T>::type APtr;
   };

   template <class T>
   struct Shared
   {
      typedef typename Internal::DeclareShared<T>::type Ptr;

      template <class... P>
      static Ptr shared(P&&... args) 
      { 
         return std::make_shared<T>(std::forward<P>(args)...); 
      }
   };

   template <class T>
   struct UniqueAbstract
   {
      typedef typename Internal::DeclareUnique<T>::type AUPtr;
   };

   template <class T>
   struct Unique
   {
      typedef typename Internal::DeclareUnique<T>::type UPtr;

      template <class... P>
      static UPtr shared(P&&... args) 
      { 
         return std::unique_ptr<T>(new T(std::forward<P>(args)...)); 
      }
   };
为作用域ptr等添加了更多接口,您可以执行以下操作:

struct Foo : public Shared<Foo>, public Unique<Foo>
{};

Foo::Ptr foo = Foo::shared();
Foo::UPtr unique = Foo::unique();

我不确定VS10如何处理可变模板,但这至少在GCC4.5+上运行良好。

我更喜欢这种方法:

   namespace Internal
   {
      template <class T>
      struct DeclareShared
      {
         typedef std::shared_ptr<T> type;
      };

      template <class T>
      struct DeclareUnique
      {
         typedef std::unique_ptr<T> type;
      };
   }

   // Inherit one of these classes to use a generic smart pointer interface.

   // If class is abstract, use this interface.
   template <class T>
   struct SharedAbstract
   {
      typedef typename Internal::DeclareShared<T>::type APtr;
   };

   template <class T>
   struct Shared
   {
      typedef typename Internal::DeclareShared<T>::type Ptr;

      template <class... P>
      static Ptr shared(P&&... args) 
      { 
         return std::make_shared<T>(std::forward<P>(args)...); 
      }
   };

   template <class T>
   struct UniqueAbstract
   {
      typedef typename Internal::DeclareUnique<T>::type AUPtr;
   };

   template <class T>
   struct Unique
   {
      typedef typename Internal::DeclareUnique<T>::type UPtr;

      template <class... P>
      static UPtr shared(P&&... args) 
      { 
         return std::unique_ptr<T>(new T(std::forward<P>(args)...)); 
      }
   };
为作用域ptr等添加了更多接口,您可以执行以下操作:

struct Foo : public Shared<Foo>, public Unique<Foo>
{};

Foo::Ptr foo = Foo::shared();
Foo::UPtr unique = Foo::unique();

我不确定VS10如何处理可变模板,但这至少在GCC4.5+上运行良好。

我在声明上可能不完整,但在使用上可能不完整。与T*@BatchyX不同,shared_ptr依赖于T的析构函数,因此在使用析构函数时,就像使用delete时一样,定义必须可用。没有这么大的变化。并非每次使用shared_ptr都会导致析构函数调用。例如,只返回从容器检索到的指针的函数不必销毁任何内容,并且可以使用不完整的类型来完成。用共享的\u ptr替换此指针会强制定义类型,即使无法在此函数中调用delete。我可以在声明上不完整,但在使用上不完整。与T*@BatchyX不同,shared_ptr依赖于T的析构函数,因此在使用析构函数时,就像使用delete时一样,定义必须可用。没有这么大的变化。并非每次使用shared_ptr都会导致析构函数调用。例如,只返回从容器检索到的指针的函数不必销毁任何内容,并且可以使用不完整的类型来完成。用共享\u ptr替换此指针会强制定义类型,即使无法在此函数中调用delete。我使用了您之前建议的typedef,但停止了这样做,因为我发现直接使用共享\u ptr更具可读性。相反,我更喜欢将shared_ptr拉入全局名称空间,以便通过使用std::shared_ptr;更容易编写;。我使用了你之前建议的typedef,但我不再这么做了,因为我发现直接使用shared_ptr更具可读性。在里面
相反,我更喜欢将shared_ptr拉入全局名称空间,以便通过使用std::shared_ptr;更容易编写;。个人品味的问题tho.叫喊“不要”有点过于戏剧化:-小心你不太想做的事情可能对人们的虚拟耳朵稍微好一点。否则我完全同意。事实上,由于它的工作原理,shared_ptr可以在向本地对象传递指针的情况下发挥作用。您可以将deleter设置为null操作,然后将其发送到下一行。你当然打破了关于共享的每一个语义,但在紧要关头,它确实起到了作用。根据定义,过于戏剧化是有问题的,如果它没有结束,一旦它被定义为过度戏剧化,它就会变得戏剧化@Motti:Bah,这只有在你相信逻辑的情况下才有问题@莫蒂:因此,这并不过分戏剧化。在这种情况下,大喊大叫“不要”是有道理的。大喊大叫“不要”有点过于戏剧化:-小心你不太想做的事情可能对人们的虚拟耳朵稍微好一点。否则我完全同意。事实上,由于它的工作原理,shared_ptr可以在向本地对象传递指针的情况下发挥作用。您可以将deleter设置为null操作,然后将其发送到下一行。你当然打破了关于共享的每一个语义,但在紧要关头,它确实起到了作用。根据定义,过于戏剧化是有问题的,如果它没有结束,一旦它被定义为过度戏剧化,它就会变得戏剧化@Motti:Bah,这只有在你相信逻辑的情况下才有问题@莫蒂:因此,这并不过分戏剧化。在这种情况下,尖叫“不要”是有道理的。