问题前瞻
1.类属于什么的范畴,偏数据还是算法?为什么要提出类?
2.对象呢?对象和类什么关系?
3.类和对象该怎么创建,怎么操作和使用?
4.构造函数、析构函数、拷贝构造函数?
难点
1.拷贝构造函数的作用,创建和使用?
1.类和对象的定义(创建)
1.1类的功能和定义
类是面向对象编程思想最好的体现者。//面向对象和面向过程的对比可以通俗地通过盖浇饭和蛋炒饭的对比来理解。
所以,类和结构体相似,是用户自定义的数据类型,宏观来说类属于数据的范畴。类用于制定数据类型的格式(类比结构体的定义)
eg:
class Box
{
public:
double length;
double breadth;
double height;
};
1.2 类的实例化——对象 的定义和初始化
对象是类的实例,类相当于是对象的抽象
eg:
Box Box1; //声明对象Box1,类型为Box
Box Box2; //声明对向Box2,类型为Box
2.对象的成员微观剖析
对象由什么构成呢?标识符(identity)、状态(state)和行为(behaviors)
2.1 对象的状态
对象的状态由数据域(属性或者变量)和当前值构成
2.2 对象的行为
对象的行为由一组函数定义。(行为、函数、方法可以替换使用)
eg://定义在内部
class Box
{
public:
double length;
double breadth;
double height;
double getVolume(void) //内联在类的内部的函数不需要inline标识符。
{
return length * breadth * height;
}
};
也可以在类的外部使用作用域运算符::
eg://定义在外部
double Box::getVolulum (void)
{
return length * breadth * height ;
}
2.3 修饰的东西:类访问修饰符
2.3.1为什么要加访问修饰符?
答:数据隐藏是面向对象编程的一个重要特点,猜想为了安全性和独立性。比如做盖浇饭的各种卤子之间不允许混杂
2.3.2 有哪些?
public:成员变量或函数访问无限制
private:默认状态,只允许类(加访问修饰符)和友元函数可以进行访问
class Box
{
double width;
public:
double length;
void setWidth( double wid );
double getWidth( void );
};
int main(){
Box box;
box.width = 12; // error
//box.length ;// OK
box.getWidth(10.0);// OK
}
protected:基本与private相似,只是在派生类(子类)中是可访问的。
2.3.1怎么用?放在哪儿?
class Base{
public:
//public members go here
protected;
// protected members go here
private:
//private members go here
};
3 几类具有特殊功能的函数
3.1 构造函数&析构函数(创建或者删除的标记)
类的构造函数是一种特殊的成员函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。
3.1.1功能
构造函数可以用于为某些成员变量设置初始值。构造函数的名称与类的名称完全相同,并且没有任何的返回值,也不会返回void.
3.1.2怎么用
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数。构造函数的名称与类的名称完全相同,并且没有任何的返回值,也不会返回void.
Line::Line(void) //也可以有参数,有参数的话往往伴随着成员变量的初始化。
{
cout << "Object is being created" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
执行结果为:
Object is being created
Length of line : 6
3.1.3利用初始化列表来初始化字段
Line::Line( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}
等同于下面的:
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:
C::C( double a, double b, double c): X(a), Y(b), Z©
{
…
}
3.2 类的析构函数
与 类的结构函数 对偶,在每次删除所创建的对象时执行。长什么样子呢?析构函数的名称就是所属类的名称加了个波浪号(~)前缀,不返回任何值,也不带有任何参数
3.2.1功能
有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
3.2.2 使用
eg:
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数声明
~Line(); // 这是析构函数声明
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
执行结果:
Object is being created
Length of line : 6
Object is being deleted
3.3 C++拷贝构造函数
拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象(哥哥姐姐)来初始化新创建的对象。
3.3.1功能
通过另一个同类型的对象来初始化新创建的对象
复制对象把它作为参数(引用作为参数)传递给函数
复制对象,并从函数返回这个对象
3.3.2 创建以及使用
如果在类中没有定义拷贝构造函数,编译器会自行定义一个,如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。//为什么呢?
最常见形式如下:
classname(const classname &obj){
// 构造函数的主体
}
下面的实例,包括通过使用已有的同类型的对象来初始化新创建的对象,复制对象把它作为参数传递给函数;
#include <iostream>
using namespace std;
class Line
{
public:
int getLength( void );
Line( int len ); // 简单的构造函数
Line( const Line &obj); // 拷贝构造函数
~Line(); // 析构函数
private:
int *ptr;
};
// 成员函数定义,包括构造函数
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
// 为指针分配内存
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void)
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)
{
cout << "Length of line : " << obj.getLength() <<endl;
}
// 程序的主函数
int main( )
{
Line line1(10);
Line line2 = line1; // 这里也调用了拷贝构造函数
display(line1);
display(line2);
return 0;
}
结果是:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!