C ++,构造函数的原因

时间:2010-12-18 07:58:56

标签: c++ constructor

我有两个问题。

1)构造函数真正做了什么?如果我们在声明实例时不使用构造函数会发生什么?

2)你能告诉我这两者之间的区别吗?

A a(1,2)

A *a = new A(1,2)

最好的问候。

5 个答案:

答案 0 :(得分:8)

构造函数初始化类的成员变量,以便可以使用它。声明实例时不使用构造函数的结果因上下文而异。

如果要在堆上分配变量,请执行以下操作:

A *a;

a将指向内存中的随机地址,直到将其分配给NULL或0,或者类的现有或新实例,例如:

A *a = new A(1, 2);

如果要在堆栈上分配变量,则使用以下语法:

A a(1, 2); // if parameters are used
A a; // if no parameters are used

以上两者都调用类A的构造函数,在堆栈上分配它的实例。因此,这可以回答您的问题 - 您的第一个示例在堆栈上分配A的实例,第二个示例在堆上分配A的实例。

答案 1 :(得分:3)

构造函数是一个与类同名的函数。构造函数的主要目的是将新创建的对象的成员变量初始化为某些默认值。它也可能调用其他初始化函数 就像C ++中的其他函数一样,构造函数可以重载。 (重载函数是具有不同参数的现有函数的新版本)。例如,考虑以下具有三个构造函数的Point类:

class Point
{
public:
    Point() : x_(0), y_(0) { }
    Point(int x, int y) : x_(x), y_(y) { }
    Point(const Point& p) : x_(p.x), y_(p.y) { }
private:
    int x_;
    int y_;
};

第一个构造函数将坐标初始化为零,而第二个构造函数允许用户指定其默认值:

void create_and_destroy_points ()
{
   Point p1; // => x_ = 0, y_ = 0
   Point p2(100, 200); // x_ = 100, y_ = 200
}

当以这种方式声明时,那些Point对象被分配在堆栈上。这意味着当create_and_destroy_points函数返回时,分配给它们的内存将自动释放。换句话说,p1p2在函数之外没有用处 对象也可以在上分配。这会在运行时分配对象,然后它们可以在各种函数调用中存活。它们使用new关键字进行分配,并继续有效,直到它们被delete取消分配。在使用后未能删除堆分配的对象将导致内存泄漏

Point* create_point ()
{
   Point* p = new Point(100, 200);
   return p;
}

Point* p = create_point();
// use p 
delete p;

第三个构造函数是复制构造函数。通过复制另一个对象构造新对象时调用它:

Point p1;
Point p2 = p1; // calls the copy constructor for p2 with p1 as argument.
Point p3(p1);  // alternate syntax

答案 2 :(得分:2)

要回答#2,你的第一个例子在堆栈上分配一个A类型的变量'a',而你的第二个分配一个指针'* a'到A类。指针被赋予一个起始值,一个地址指向动态记忆。在这两种情况下,A :: A()构造函数都被称为2参数

答案 3 :(得分:2)

  

1)构造函数真正做了什么?

对象的构造由两部分组成:

  1. 分配所需的内存量

  2. 在构造函数中执行代码

  3.   

    如果我们不使用会发生什么   建设者同时宣布一个   实例

    即使您没有显式调用构造函数,也始终执行构造函数。例如:

    std::string a;
    

    这里将调用字符串类的默认构造函数。

      

    2)你能告诉我不同​​之处吗?   这两者之间?

    A a(1, 2);
    

    此代码调用用户定义的构造函数。

    A a;
    

    此代码调用默认构造函数。

答案 4 :(得分:2)

1)构造函数应仅用于成员变量初始化。

class A {
public:
    A() { a = 0; b = 0; }
    A(int a, int b) { this->a = a; this->b = b; }

private:
    int a;
    int b;
};

在上面的类中,我们有两个构造函数,每个构造函数初始化成员变量,一个使用零,另一个使用给定的参数。

类可以包含任意数量的构造函数。创建类实例时,必须始终调用其中一个,例如:

A a1;    // uses first constructor, i.e. A::A() 
A a2();  // also uses first constructor

A* a3 = new A(1, 2); // uses second constructor, i.e. A::A(int a, int b) 
A a4(1, 2);          // also uses second constructor

2)声明:

A a(1, 2)

声明保存绑定到作用域的实例的变量,这意味着当程序退出该作用域时将自动删除该实例。例如:

void fn() {
    A a(1, 2);
    ...
    ...
}

在构造函数实例的过程中构造a,当我们退出该函数时,它将被自动删除。

如果:

A *a = new A(1,2)

声明变量a,它指向新创建的A实例。您必须手动删除带有“删除”的点的实例,但您的实例可以在声明a的范围内存活。例如:

A* fn()
{
    A *a = new A(1,2)
    return a;
}

这里,函数fn返回在其体内创建的实例,即实例在函数范围内存活。