结构化程序设计: 程序 = 数据结构+算法
函数和其所操作的数据结构没有直观的联系。
随着程序规模的增加,程序逐渐难以理解。
重用性差。
面向对象的程序设计
- 某类客观事物的共同特点(属性)归纳出来,形成一个数据结构(用多个变量描述事物的属性)
- 将所能进行的行为也归纳出来,行成一个个函数,这些函数可以操作数据机构(抽象)
- 特点:抽象、封装、继承、多态
例: 写一个程序,输入矩形的长和宽,输出周长和面积
长和宽是成员变量,设置长和宽、求周长、求面积为该类的成员函数,成员变量和成员函数统称为类的成员
#include <iostream>
#include <stdio.h>
class CRectangle{
public:
int w, h;
int Area(){
return w*h;
}
int Perimeter(){
return 2*(w+h);
}
void Init(int w_, int h_){
w = w_;
h = h_;
}
}; // 记得分号
int main(){
int w,h;
CRectangle r; // r是一个对象
std::cin>>w>>h;
r.Init(w,h);
std::cout<<r.Area()<<"\n"<<r.Perimeter();
return 0;
}
对象的内存分配
和结构体变量一样,对象所占用的内存空间大小,等于所有成员变量的大小之和。
访问成员变量和成员函数的方法
- 对象.成员
- 指针->成员
- 引用名.成员
类的成员函数和类的定义分开写
// 类的定义
class A{
public:
int w,h;
int Area(); // 成员函数声明
int Perimeter();
void init(int w_, int h_);
};
int A::Area(){
return w*h;
}
int A::Perimeter(){
return 2*(w+h);
}
void A::init(int w_, int h_){
w = w_;
h = h_
}
A::说明后面的函数是类A的成员函数
类成员的可访问范围 默认是私有的
- private 私有 类里面访问
- public 公有。内外均可访问
- protected 受保护的
成员函数的重载及参数缺省
需避免函数重载时的二义性
构造函数 对象的内存并不是构造函数分配的,构造函数只是在生成对象后去进行初始化操作
-
名字和类名一样,可以有参数,不能有返回值。
-
作用是对对象进行初始化,如给成员变量赋值
-
如果定义类时没有写构造函数,则编译器生成一个默认的无参数构造函数,默认构造函数无参数,不进行任何操作
-
一个类可以有多个构造函数
-
对象生成时构造函数自动被调用,对象一旦生成,就再也不能再其上执行构造函数。
class Complex{
private:
double real, image;
public:
void Set(double r, double i);
}; //编译器自动生成默认构造函数
Complex c1; //默认构造函数被调用
Complex* c2 = new Complex; // 默认构造函数被调用
class Complex{
private:
double real, image;
public:
Complex(double r, double i=0); //自定义构造函数
};
Complex::Complex(double r, double i){
real = r;
image = i;
}
Complex c1 ; // 缺少构造函数 编译不过
Complex* c2 = new Complex; // 没有参数 编译不过
Complex c1(2); //ok 缺省了
Complex* c3 = new Complex(3, 2);//ok
构造函数在对象数组初始化时的调用情况
Complex c1_array[2]; // 默认调用无参数的构造函数即constructor1
Complex c2_array[2] = {1,2}; // 两个对象调用constructor2
Complex c3_array[2] = {1}; // 第一个对象调用constructor2 第二个对象调用constructor1
// constructor1,constructor2,constructor2
Complex c4_array[3] = {Complex(), Complex(2), 2};
Complex* pArray[3]; // 指针数组是不会自动创建对象的
Complex* pArray2[3] = {new Complex(), new Complex(3)}; // constructor1, constructor2 第三个指针没有指向任何元素
复制构造函数 一个类一定有且一个复制构造函数
- 形如A::A(A&) 或 A::A(const A&)
- 如果没有手动定义复制构造函数,编译器会默认生成
class Complex{
private:
double real;
public:
Complex();
Complex(double r); //自定义构造函数
Complex(const Complex& c); // 自定义复制构造函数
};
Complex::Complex(){
std::cout<<"constructor 1 called"<<std::endl;
}
Complex::Complex(double r){
real = r;
std::cout<<"constructor 2 called"<<std::endl;
}
Complex::Complex(const Complex& c){
real = c.real;
}
Complex c1; // 调用无参构造函数初始化
Complex c2(c1);// 调用缺省的复制构造函数将c2初始化成和c1一样
注意:A::A(A)不是复制构造函数, 必须是引用类型作为形参 会报错