【问题标题】:private constructor [duplicate]私有构造函数[重复]
【发布时间】:2011-06-06 14:57:58
【问题描述】:

可能重复:
What is the use of making constructor private in a class?

我们在哪里需要私有构造函数?我们如何实例化具有私有构造函数的类?

【问题讨论】:

标签: c++ private-constructor


【解决方案1】:

一种常见的用法是在单例模式中,您只希望类的一个实例存在。在这种情况下,您可以提供一个 static 方法来实例化对象。这样可以控制特定类的实例化对象的数量。

【讨论】:

  • +1。当我提到单例作为特定习语的案例用法时,我总是被否决。不希望这种事情发生在你身上! :)
【解决方案2】:

当您想要实现单例时,这很常见。该类可以有一个静态的“工厂方法”来检查该类是否已经被实例化,如果没有,则调用构造函数。

【讨论】:

    【解决方案3】:

    如果有其他方法可以产生实例,将构造函数设为私有是合理的。明显的例子是模式 Singleton(每个调用返回相同的实例)和 Factory(每个调用通常创建新实例)。

    【讨论】:

      【解决方案4】:

      例如,您可以在友元类或友元函数中调用私有构造函数。

      Singleton pattern 通常使用它来确保没有人创建更多预期类型的​​实例。

      【讨论】:

        【解决方案5】:

        私有构造器意味着用户不能直接实例化一个类。相反,您可以使用 Named Constructor Idiom 之类的东西创建对象,其中有 static 类函数,可以创建和返回类的实例。

        Named Constructor Idiom 用于更直观地使用类。 C++ FAQ 中提供的示例是针对可用于表示多个坐标系的类。

        这是直接从链接中提取的。它是一个表示不同坐标系中的点的类,但它既可以表示直角坐标点,也可以表示极坐标点,所以为了让用户更直观,使用不同的函数来表示返回的Point代表什么坐标系。

         #include <cmath>               // To get std::sin() and std::cos()
        
         class Point {
         public:
           static Point rectangular(float x, float y);      // Rectangular coord's
           static Point polar(float radius, float angle);   // Polar coordinates
           // These static methods are the so-called "named constructors"
           ...
         private:
           Point(float x, float y);     // Rectangular coordinates
           float x_, y_;
         };
        
         inline Point::Point(float x, float y)
           : x_(x), y_(y) { }
        
         inline Point Point::rectangular(float x, float y)
         { return Point(x, y); }
        
         inline Point Point::polar(float radius, float angle)
         { return Point(radius*std::cos(angle), radius*std::sin(angle)); }
        

        还有很多其他的回应也符合 C++ 中为何使用私有构造函数的精神(其中包括单例模式)。

        你可以用它做的另一件事是prevent inheritance of your class,因为派生类将无法访问你的类的构造函数。当然,在这种情况下,您仍然需要一个创建类实例的函数。

        【讨论】:

        • 不确定,但最好有 copy ctor。不确定,因为 RVO。
        • @Pawel - C++ FAQ 示例没有为Point 定义复制构造函数,因为该类只有原始成员(两个float),所以编译器的默认复制构造函数(执行浅拷贝) 就足够了。
        • +1 最后,一个不是 Singleton 或 Factory 的示例。命名构造函数似乎更有用。
        • 谢谢大家,这真的很有帮助...:)
        • 我只是偶然发现了你的句子“......返回的点代表什么坐标系”。无论使用什么构造函数来创建对象,点本身都使用直角坐标(否则恕我直言,这将是一个不好的例子)。我检查了常见问题解答,我认为那里的公式可能会产生误导:“......在任一坐标系中创建点:”。我认为最好说:“通过在任一坐标系中提供坐标作为参数来创建点(使用直角坐标)。我可能听起来很挑剔,但对于像我这样的新手来说,这样的想法可以有所作为
        【解决方案6】:

        当您不希望您的类被用户实例化时,私有构造函数很有用。要实例化此类类,您需要声明一个静态方法,该方法执行“新”并返回 指针。

        不能将具有私有 ctor 的类放入 STL 容器中,因为它们需要复制 ctor。

        【讨论】:

          【解决方案7】:

          一个常见的用途是模板类型定义解决方法类,如下所示:

          template <class TObj>
          class MyLibrariesSmartPointer
          {
            MyLibrariesSmartPointer();
            public:
              typedef smart_ptr<TObj> type;
          };
          

          显然,一个公共的未实现的构造函数也可以工作,但是如果有人试图实例化 MyLibrariesSmartPointer&lt;SomeType&gt; 而不是 MyLibrariesSmartPointer&lt;SomeType&gt;::type,那么私有构造函数会引发编译时错误而不是链接时错误,这是可取的。

          【讨论】:

            猜你喜欢
            • 2016-09-11
            • 1970-01-01
            • 2019-03-02
            • 2011-04-20
            • 2019-10-16
            相关资源
            最近更新 更多