2010-12-18 63 views
3

我有两个问题。C++,构造函数的原因

1)构造函数的功能是什么?如果我们在声明实例时不使用构造函数会发生什么?

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

A a(1,2) 

A *a = new A(1,2) 

此致敬礼。

+3

看起来像我的功课。 – 2010-12-18 08:19:32

+1

[使用new和without实例化对象之间有什么区别]的可能的重复(http://stackoverflow.com/questions/3673998/what-is-difference-between-instantiating-an-object-using-new-vs -without) – fredoverflow 2010-12-18 08:36:23

回答

8

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

如果您在堆上分配一个变量,像这样:直到它被指定为NULL或0,或者一个现有的或新的实例

A *a; 

a将指向内存中的随机地址类,如:

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

如果您在堆栈上分配一个变量时,使用的语法如下:

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

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

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,第一个实施例分配一个变量“a”在栈上A型的,而第二个一个分配一个指针“* a”到A型的指针被给定一个初始值,地址指向动态内存。在这两种情况下,A :: A()构造函数被称为取2个参数

2

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

对象的构建由两个部分组成:

  1. 分配所需的存储器量的代码

  2. 执行在构造

会发生什么如果我们不使用 构造函数同时声明一个 实例?

构造函数总是被执行,即使你没有显式地调用它们。例如:

std::string a; 

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

2)你能告诉我这两者之间的差异 ?

A a(1, 2); 

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

A a; 

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

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 = new A(1,2) 

变量声明,并将其指向A的新创建的实例,您必须手动删除实例上用点“删除”,但您的实例可以生存a的声明范围。例如:

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

在这里,函数fn返回在其主体内创建的实例,即实例存在于函数作用域中。