如果构造函数在私有部分,为什么我们不能创建Object?

时间:2010-04-22 10:10:37

标签: c++ object constructor private

我想知道为什么我们无法在构造函数位于私有部分时创建对象。我知道如果我使方法静态,我可以使用

调用该方法
<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();
}

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

4 个答案:

答案 0 :(得分:9)

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

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

“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();

答案 3 :(得分:2)

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

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

选项1 是制作构造函数。在绝大多数情况下,这是正确的事情。构建一个构造函数private是一种有用的技术,但只有在尝试实现特定目标时才会使用。

选项2 是创建public static工厂方法。当选项1不是一个选项时,通常会这样做。

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();
}