1、默认构造函数
定义默认构造函数的方法有两种:
(1)如果没有提供任何构造函数,C++将创建默认构造函数。该默认构造函数不接受任何参数,也不执行任何操作。格式如下:
Stonewt::Stonewt(){ } //implicit default constructor
可以显示的定义该默认构造函数,使用它来设置特定的值。如:
Stonewt::Stonewt() //expicit default constructor
{
stone=0;
...
}
(2) 带参数的构造函数也可以是默认构造函数,只要所有参数都有默认的值。例如,Stonewt类可以包含下列内联构造函数:
Stonewt(int n=0){stone=n;}
只能存在一个默认构造函数。
通常应初始化所有的对象,以确保所有成员一开始就有已知的、合理的值。因此,默认构造函数通常给所有成员提供隐式初始值。例如,下面是为Stock类定义的一个默认构造函数:
Stock::Stock()
{
std::strcpy(company,"no name");
shares=0;
share_val=0.0;
total_val=0.0;
}
构造函数的初始化的几种方法:
方法一:
Stock stock1("test",2,2.0);
方法二:
Stock stock2=Stock("test2",3,3.0);
方法三:
Stock * stock3=new Stock("test3",4,4.0);
方法四:
stock2=stock1;//将对象stock1赋值给stock2,stock1的内容将覆盖stock2的内容。
对于只有一个参数的构造函数,如Stock(int n),其初始化:
Stock stock1(23);
Stock stock2=Stock(34);
Stock stock3=54;
不要试图将类成员名称用作构造函数的参数,如下:
Stock::Stock(const char * company,int shares,double share_val)
{
...
}
这是错误的。构造函数的参数表示的不是类成员,而是赋给类成员的值。因此参数名不能与类成员相同,否则最终的代码将是这样的:
shares=shares;
为避免这种混乱,通常的做法是在数据成员名中使用m_前缀:
class Stock
{
private:
int m_shares;
...
(3)构造函数是不能继承的,即在创建派生类时,必须调用派生类的构造函数。不过,派生类构造函数通常使用成员初始化列表句法来调用基类构造函数,以创建派生对象的基类部分。如果派生类构造函数没有使用初始化列表句法显示调用基类构造函数,将使用基类的默认构造函数。在继承链中,每个类都可以使用成员初始化列表将信息传递回相邻的基类。
2、new和delete
class Act{...};
...
Act nice; //external object
...
int main()
{
Act *pt=new Act; //dynamic object
{
Act up; //automatic object
...
} //-------------------------------a
delete pt; //----------------------------b
...
} //-------------------------------c
a、当执行到达定义数据块的结尾时,调用动态对象up的析构函数;
b、当delete操作符用于指针pt应用时,调用动态对象*pt的析构函数;
c、当执行到达整个程序的结尾时,调用静态对象nice的析构函数
3、析构函数
在下述情况下析构函数将被调用:
- 如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数。
- 如果对象是静态变量(外部、静态、静态外部或来自名称空间),则在程序结束时将调用对象的析构函数。
- 如果对象是new创建的,则仅当你显示地使用delete删除对象时,其析构函数才会被调用。
- 按值传递对象时,会生成临时拷贝,即调用复制构造函数,然后调用析构函数。
- 返回对象时,会生成返回对象的临时拷贝,即调用复制构造函数,然后调用析构函数删除临时拷贝。
函数mian()结束时,在main()函数中的局部变量将消失。由于这种自动变量被放在堆栈中,因此最后创建的对象将最先被删除,最先被创建的对象将最后被删除。
程序创建派生类对象时,将首先调用基类的构造函数,然后调用派生类的构造函数;程序删除对象时,将首先调用派生类的析构函数,然后调用基类的析构函数。
4、私有成员和保护成员
对派生类而言,保护成员类似于公有成员;但对于外部而言,保护成员会私有成员类似。派生类可以直接访问基类的保护成员,但只能通过基类的成员函数来访问私有成员。因此,将基类成员设置为私有的可以提高安全性,而将他们设置为保护成员则可简化代码的编写工作,并提高访问速度。