如果构造函数在私有部分,为啥我们不能创建对象?

Posted

技术标签:

【中文标题】如果构造函数在私有部分,为啥我们不能创建对象?【英文标题】:Why cant we create Object if constructor is in private section?如果构造函数在私有部分,为什么我们不能创建对象? 【发布时间】:2011-02-11 00:04:54 【问题描述】:

我想知道如果构造函数在私有部分中,为什么我们不能创建对象。我知道如果我将方法设为静态,我可以使用

调用该方法
<classname> :: <methodname(...)>;

但为什么我们不能创建对象是我不明白的。

我也知道如果我的方法不是静态的,那么我也可以通过以下方式调用函数:

class A

     A();
     public:
        void fun1();
        void fun2();
        void fun3();
;


int main()

     A *obj =(A*)malloc(sizeof(A));
     //Here we can't use new A() because constructor is in private 
     //but we can use malloc with it, but it will not call the constructor
     //and hence it is harmful because object may not be in usable state.
     obj->fun1();
     obj->fun2();
     obj->fun3();

所以,我的问题是:为什么我们不能在构造函数是私有的时候创建一个对象?

【问题讨论】:

这不是有史以来最伟大的问题,但我认为它不值得被否决。 【参考方案1】:

因为程序无法访问它,所以这就是私有的意思。如果您将成员函数或变量声明为私有,您也将无法访问它们。在 C++ 中创建私有构造函数实际上是一种有用的技术,因为它允许您说只有特定的类才能创建该类型的实例。例如:

class A 
   A()  // private ctor
   friend class B;
;

class B 
   public:
     A * MakeA() 
        return new A;
     
;

只有 B 可以创建 A 对象 - 这在实现工厂模式时很有用。

【讨论】:

我可以通过任何其他方式创建不使用 malloc 的对象。使用 malloc 时,对象可能不处于可用状态。 @Abhi 公开构造函数 @Neil Butterworth:非常感谢。我正在寻找这个答案。谢谢你的朋友.... @Andreas Brinck :如果我必须这样做。我不会在堆栈溢出中发表我的疑问。问题是如果构造函数是私有的,那么如何在不使用 malloc 的情况下创建对象。 @Ahbi:如果你想让你的构造函数保持私有并且仍然能够实例化你的类,你需要实现一个静态工厂方法。我将发布一个回复,说明如何做到这一点。【参考方案2】:

构造函数是一个特殊的成员函数。在访问它时,它遵循与任何其他方法相同的规则。私有访问标签防止类用户调用/访问在其下声明的成员。

【讨论】:

【参考方案3】:

“new”操作符需要调用构造函数,所以如果构造函数是私有的,除了类A本身的成员函数之外,你不能执行代码“obj = new A”。

我猜你遇到的是一种在 Java 中经常使用的技术(是的,我知道你正在编写 C++,但原理是一样的),类的设计者想要确保此类的一个且只有一个实例将永远存在(称为“单例”)。为了实现这一点,他需要防止其他代码使用 new 创建该类的更多实例,而将构造函数设为私有是一种方法。这是一段说明该技术的 Java 代码。

public class MySingleton 

  private MySingleton() 
      // Private constructor, to prevent instantiation using "new"
      // outside of this class.
  

  public synchronized static MySingleton getInstance() 
    static MySingleton instance = null;

    if (instance == null) 
        // I can use new here because I'm inside the class.
        instance = new MySingleton();
    
    return instance;
  


即使您不了解 Java,其语法也与 C++ 非常相似,您应该了解这段代码在做什么。关键是,在代码的其他地方获取对 MySingleton 类实例的引用的唯一方法是调用静态类成员 getInstance()。

  MySingleton obj = MySingleton.getInstance();

【讨论】:

【参考方案4】:

你不能实例化你的类,因为构造函数是privateprivate 成员变量和函数不能在类本身之外使用。

如果您希望能够实例化您的类,您有两种选择。

选项1是制作构造函数。在绝大多数情况下,这是正确的做法。创建构造函数private 是一种有用的技术,但仅限于尝试完成特定目标时。

选项2是创建一个public static工厂方法。 You would typically do this when Option 1 isn't an option.

class A

     A();
     public:
    static A* Create()  return new A; 
        void fun1();
        void fun2();
        void fun3();
;


int main()

     A *obj = A::Create();
     //Here we can't use new A() because constructor is in private 
     //but we can use malloc with it, but it will not call the constructor
     //and hence it is harmful because object may not be in usable state.
     obj->fun1();
     obj->fun2();
     obj->fun3();

【讨论】:

@John Dibling:谢谢你的朋友

以上是关于如果构造函数在私有部分,为啥我们不能创建对象?的主要内容,如果未能解决你的问题,请参考以下文章

为什么构造器私有之后不能创建对象了?

特殊作用的私有成员函数

我们啥时候需要 C++ 中的私有构造函数?

为啥私有构造函数在案例类中仍然可见?

创建对象

构造函数为什么不能为虚函数