【问题标题】:C++ What syntax for avoid duplicated declarations?C++ 避免重复声明的语法是什么?
【发布时间】:2020-06-09 16:20:11
【问题描述】:

我正在学习 C++,尤其是 OO 编程。

我的程序使用指针来处理动态内存分配。

在创建我的默认构造函数时,我对重复自己感到很无聊

myInt = new int;
myOtherInt = new int; 

等等。

所以我的问题是:有没有办法写出类似的东西:

myInt, myOtherInt = new int;

这是我的构造函数代码:

Annonce::Annonce(string Titre, long double Prix, string Intro, string Description, vector<vector<string>> ImgUrls) {

    titre = new string;
    intro = new string;
    description = new string;
    imgUrls = new vector<vector<string>>;
    prix = new long double;

    id = new size_t;
    *id = nbAnnonces;

    *titre = std::move(Titre);
    *prix = Prix;
    *intro = std::move(Intro);
    *description = std::move(Description);
    *imgUrls = std::move(ImgUrls);

}

【问题讨论】:

  • "我的程序使用指针来处理动态内存分配。"必须吗?而不是你的班级由std::string *std::vector &lt;&gt;*组成,它可以只容纳std::stringstd::vector吗?这些对象自己处理动态内存分配,所以我们不必这样做。
  • 我 99.9% 确定您不需要这些指针。看看这个构造函数的外观:stackoverflow.com/questions/1711990/…
  • myInt = new int; 应该是您几乎从不做的事情。与intro = new string; 相同
  • 你几乎不应该直接使用new(除非可能作为std::shared_ptrstd::unique_ptr成员的参数)。你在这里特别展示的例子显然是错误的。见Why should C++ programmers minimize use of 'new'?。如果您的教学材料教您像这样编写 C++,那么我建议您停止使用该材料并改用 recommended C++ books 之一。
  • C++ 不是 Java。 new 在 Java 中可能是例行公事,但在 C++ 中应该避免或最小化它,因为 walnut 指出的原因。

标签: c++ class c++11 constructor


【解决方案1】:

从动态内存中分配多个变量没有捷径。

分配内存的函数返回单个内存地址(指针)。每个变量在内存中都应该有自己的、唯一的位置。

为了支持返回多个地址(指针)的动态内存函数,需要更改 C++ 语言的语法。

一个建议是减少内存分配的数量。问问自己,“我真的需要从动态内存中分配吗?”在从动态内存分配之前。

【讨论】:

    【解决方案2】:

    第一个预回答建议:不要这样做。

    第二个预回答建议:避免自我管理的内存分配/释放,而是使用 STL 容器和/或智能指针(std::unique_ptrstd::shared_ptr 等)

    回答:不,据我所知你不能写成

    int * myInt, myOtherInt = new int;
    

    分配两个变量(分配不同的指针)。

    但是您可以将指针包装在自动分配包含的指针的类或结构中(并且可能在析构函数中销毁它)。

    只是为了好玩...如果您按如下方式编写包装器

    template <typename T>
    struct wrappPnt
     {
       T * pnt = new T{};
    
       T & operator * ()
        { return *pnt; }
    
       T const & operator * () const
        { return *pnt; }
    
       ~wrappPnt ()
        { delete pnt; }
     };
    

    你可以这样写你的Annonce

    struct Annonce
     {
       wrappPnt<std::string>  titre, intro, description;
       wrappPnt<std::vector<std::vector<std::string>>> imgUrls;
       wrappPnt<long double>  prix;
    
    
       Annonce (std::string Titre, long double Prix, std::string Intro,
                std::string Description,
                std::vector<std::vector<std::string>> ImgUrls)
        {
          *titre = std::move(Titre);
          *prix = Prix;
          *intro = std::move(Intro);
          *description = std::move(Description);
          *imgUrls = std::move(ImgUrls);
        }
     };
    

    第一次发布答案建议:不要这样做。

    第二个帖子回答建议:避免自我管理的内存分配/释放,而是使用 STL 容器和/或智能指针(std::unique_ptrstd::shared_ptr 等)

    【讨论】:

      【解决方案3】:

      有没有办法写出类似的东西:

      myInt, myOtherInt = new int;
      

      是的,有两种方法。但第一个比你具体要求的更笼统......

      1。优先使用值类型而不是引用类型

      如果您不知道这些是什么:Value types and Reference Types(维基百科)。

      在某些编程语言中,几乎所有变量、函数参数、类字段等 - 都是引用。一个突出的例子是Java。但是在 C++ 中——尤其是现在——我们更喜欢值而不是引用,除非有充分的理由不直接使用值。值语义在语言中很常用并且得到很好的支持,并且大多数使用它们更容易。另见:

      Why are pointers not recommended when coding with C++11

      具体来说,这意味着在定义结构或类时,我们会给它非指针成员。在你的情况下:

      class Announcement {
      public:
          using url_type = std::string; // perhaps use a URL library?
          using image_urls_container_type = std::unoredered_set<url_type>;
              // I'm guessing the URLs aren't really ordered
      
          std::string title;
          std::string introduction;
          std::string description;
          std::vector<image_urls_container_type> image_urls;
              // Are the images really a sequence of indices? Shouldn't this be something like
              // std::unordered_map<image_id_type,image_urls_container_type> image_urls ?
          long double prize;
          std::size_t id;
      
          Announcement() = delete;
          // constructors here, if you like
      }
      

      现在,我并不是说这一定是最好的定义,或者它符合您的所有需求。但是如果你这样定义,你会得到:

      • 永远不需要使用new
      • 无需删除任何内容。
      • 没有内存泄漏的机会(由于这个类)

      2。否则,使用std::unique_ptr

      std::unique_ptr&lt;T&gt; 类可让您避免自己管理内存 - 它会处理这些问题。所以如果你让你的成员std::unique_ptr's,你可以使用get()初始化他们指向的值,例如:

      void foo(int x) {
          auto p = std::make_unique<p>();
          p.get() = x;
          // do stuff with p
      
          // ...
      
          // no need to delete p at the end of the function
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        • 2011-03-17
        • 2011-03-27
        • 2018-04-27
        相关资源
        最近更新 更多