2016-12-28 83 views
2

我一直读到私人构造函数阻止对象创建。 我已经在singleton模式中使用它们,我知道如何使用私有构造函数创建对象(使用静态方法等)。 我知道构造函数用于对象的初始化。为什么私人构造函数阻止对象创建C++

但我不明白究竟是什么让私人构造函数阻止对象的创建。 如果我的对象没有初始化,该怎么办?我的意思是它应该抛出一些垃圾,但为什么它会限制?

我已经检查了所有在stackoverflow现有的答案,但我没有得到确切的概念。

回答

3

要在C++对象,一个构造需要叫做。如果需要调用的构造函数不可访问,则无法调用它,并且无法创建该对象。

构造函数private的点不是阻止对象构造。它关于控制哪些代码可以访问构造函数,并因此限制创建该类的实例的对象的代码。所有类的成员函数(static或其他)以及类的所有声明的friend(可能是单个函数或其他类)都可以访问构造函数,因此任何这些构造函数都可以创建类的实例使用private构造函数(假定构造函数已定义)。

如果无法调用构造函数,则无法初始化该对象。毕竟,构造函数的工作是初始化该对象。但是,如果构造函数不可访问,则该对象不能构造,因此不可能有未初始化的对象。

当然,没有什么能够阻止班级拥有不同访问控制的多个构造函数(privateprotectedpublic)。一个classpublic构造函数可以构造,使用该构造函数,任何代码。但是任何尝试使用构造函数(由非成员非friend)构造函数仍将被拒绝。因此,访问控制允许(开发人员)控制实例的构建方式。

未定义(即不实现)构造函数确实会阻止构造对象。如果该构造函数是private,编译器将拒绝尝试调用它(除非尝试创建实例的函数是成员或如上所述的friend)。对于类的成员和朋友,编译器将允许访问构造函数,但是(在典型的编译后链接工具链中),链接器不会构建可执行文件,因为它无法解析对未定义函数的调用。使用标记构造函数private而不定义它的技术是防止代码构造类的实例(通过阻止代码编译或阻止代码运行)的常用方法。

+0

所以我明白,对象和构造函数之间的关系是1)我创建一个对象“ClassName obj”2)此声明调用Class构造函数“ClassName()”3)此构造函数分配内存。这完成了对象创建过程。如果我的对象无法调用构造函数,则不会分配内存,也不会创建对象。我的理解是否正确? - –

+0

不完全。使用'ClassName obj;'创建一个对象可以调用一个不能接受参数的构造函数 - 它可能是一个没有实际参数的构造函数('ClassName :: ClassName()'),或者是一个所有参数都有默认值的构造函数类定义为'ClassName(int x = 0)')。该对象的内存(ClassName的实例)在构造函数被调用之前被分配,然后被构造函数初始化(松散地变成一个对象)。如果构造函数不可访问,编译器不允许构造该对象,所以代码将不会编译。 – Peter

2

C++不允许在不调用构造函数的情况下创建对象。如果构造函数不可访问,则创建无法完成。对象的生命周期是,定义为,它位于构造函数和析构函数的调用之间。

您当然可以分配原始内存并将其转换为指向对象类型的指针(如在C中所做的那样),但您不会拥有该类的对象。在调用构造函数将原始内存区域转换为对象表示之前,该内存区域不会正式包含对象。

0

因为您不能从类外部调用私有类方法,并且如果构造函数是私有的,这意味着您不能创建该类的实例,因为创建该对象需要构造函数才能被调用。

构造函数在这方面与其他类方法没有区别。如果一个类的方法是私人的,你已经明白你不能从课堂外调用它。并且由于必须调用构造函数来构造类的实例,并使用私有构造函数。

+0

因此从所有的上述评论据我所知,对象和构造之间的关系是 1)I创建一个对象“的ClassName OBJ” 2)此声明调用类构造函数“类名()” 3)此构造分配内存。这完成了对象创建过程。 如果我的对象无法调用构造函数,将不会分配内存,并且不会创建对象。 我的理解是否正确? –

4

这是不正确的说,标记构造函数私人将阻止对象创建。它只是用限制只用私有构造函数将对象创建到类中的代码中。您可以创建一个新对象,而其他人则不能。

这对单身人士很有效,因为它可以帮助您确保您的单身人员仍然是班级的唯一实例。

3

类专用范围不会阻止类实例化,但实际上它会限制“谁”可以创建对象。

它像私人范围的其他部件的数据不能从外部访问,但仅针对accessorsgetters等`朋友函数和类:

#include <iostream> 
using namespace std; 

class Foo 
{ 
    public: 
     Foo(int x) : value(x){ cout << "Foo(int) public ctor" << endl;} // ctor 

     void SetValue(int x) {value = x;} // setter 
     int GetValue()const{return value;}// getter 

    private: 
     int value; 
     Foo(){ cout << "Foo() private ctor" << endl;} // private ctor 

     friend ostream& operator<<(ostream& out, Foo& rhs) 
     { 
      out << rhs.value; 
      return out; 
     } 
     friend Foo* CreateObject(); 
}; 

Foo* CreateObject() 
{ 
    Foo* ptrFoo = new Foo; 
    return ptrFoo; 
} 


int main() 
{ 

    //Foo theFoo;  // error C2248: 'Foo::Foo' : cannot access private member declared in class 'Foo' 
    Foo theFoo2(0); // ok 
// cout << theFoo2.value << endl; // error C2248: 'value' : cannot access private member declared in class 'Foo' 
    cout << theFoo2.GetValue() << endl; // ok 
    cout << theFoo2 << endl; 

    Foo* ptrFoo = CreateObject(); 
    ptrFoo->SetValue(7); 
    cout << ptrFoo->GetValue() << endl; 


    cout << endl; 
    return 0; 
} 
相关问题