过程性编程:首先考虑要遵守的步骤,然后考虑如何表示这些数据
OOP方法:首先从用户角度考虑对象—描述对象所需的数据以及描述用户与数据交互所需要的 *** 作。完成对接口的描述后,需要确定如何实现接口和数据存储,最后,使用新的设计方案创建出程序。
类的定义一般放在头文件里,使用class关键字定义,并且类名称第一个大写:
# student.h
#include
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
std::string name;
double scores;
int age;
public:
void show();
};
#endif
void Student::show() {
std::cout << "the student name is:" << name << std::endl;
std::cout << "the student age is:" << age << std::endl;
std::cout << "the student scores is:" << scores << std::endl;
}
下来详细解释这段代码。#ifndef…#endef,之前介绍过,就不多说了。类中一共分为两部分,一部分private(私有),另一部分pubilc(共有)。私有表示该里边的变量时私有的,不允许外部访问,而共有部分可以直接访问,所以只能通过共有部分的函数去访问私有变量,这体现了类的封装性,以及对数据的保护。
其次,一般函数都会放在共有部分,称之为成员函数。成员函数的原型都会放在类中,如示例中的void show。函数的定义放在文件中,定义时,函数前面使用作用域解析运算符来表示函数所属的类:Student::show()。但是,可以将函数的定义也放在类声明中,这样定义的函数将会变成内联函数,因此,可以将一些短小的函数定义放在类声明中,变成内联函数。最后,使用成员函数,与结构相同,通过成员运算符。如,stu1时已经声明的成员对象:stu1.show()。
虽然现在我们可以像初始化int或者结构那样初始化类对象,而只能通过成员函数给变量赋值,为此,c++提供一种特殊的函数-----构造函数,专门用于构造新对象,将值赋给他们的数据结构。构造函数的名称与类名相同,并且,构造函数的原型和函数头有一个有趣的特征----虽然没有返回值,但没有被声明为void类型,实际上,构造函数没有声明类型。
与成员函数相同,构造函数原型在类的共有部分,定义在文件中。
#pragma once
#include
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
std::string name;
double scores;
int age;
public:
Student(const std::string , double , int );
void show();
};
#endif
# class.cpp
Student::Student(const std::string na, double sc, int ag) {
name = na;
scores = sc;
age = ag;
}
c++提供了两种使用构造函数来初始化对象的方式:
Student stu1 = Studnet("kyle", 85.6, 18);
Student stu2 ("smith", 60.5, 19);
第一种时显式的调用构造函数,第二种是隐式的调用构造函数,这样格式更紧凑。
默认构造函数:在未提供显式初始值时,用来创建对象的构造函数,如果没有提供任何的构造函数,c++将自动提供默认的构造函数,这样不能初始化其成员,默认构造函数中没有参数
Studnet::Student(){ }
这是定义默认构造函数的方法之一,另一种是给已有的构造函数的所有参数提供默认值。但默认构造函数只能有一个,因此两种方法二选一。
析构函数:用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止,对象过期时,程序将自动调用一个特殊的成员函数----析构函数。析构函数完成清理工作,例如在构造函数使用new分配空间,那么析构函数中就要使用delete清理空间。析构函数名称也很特殊,类名前加~,与构造函数不同的是,析构函数没有参数,其原型:
~Student();
定于方式与其他成员函数相同。
下面是一个综合的示范:
//student.h
#pragma once
#include
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
std::string name;
double scores;
int age;
public:
Student(); //默认构造函数
Student(const std::string , double , int ); //传递三个变量
Student(const std::string &); //传递一个变量
void show();
~Student(); //析构函数
};
#endif
// class.cpp
#include
#include"student.h"
Student::Student(const std::string na, double sc, int ag) {
name = na;
scores = sc;
age = ag;
}
Student::Student()
{
name = "None";
scores = 0.0;
age = 0;
}
Student::Student(const std::string &na) {
name = na;
age = 0;
scores = 0.0;
}
void Student::show() {
std::cout << "the student name is:" << name << std::endl;
std::cout << "the student age is:" << age << std::endl;
std::cout << "the student scores is:" << scores << std::endl;
}
Student::~Student() {
std::cout << "bee " << name << " ! "<
//index.cpp
#include
#include"student.h"
int main() {
Student stu1;
Student stu2("kyle", 80.1, 17);
Student stu3("smith");
stu1.show();
std::cout << "-------------------------" << std::endl;
stu2.show();
std::cout << "-----------------------------" << std::endl;
stu3.show();
std::cout << "-----------------------------" << std::endl;
return 0;
}
this指针
现在新声明一个成员函数,比较两个对象的分数,并返回分数高的对象。需使用a对象的该成员函数,参数是b对象。或者使用b对象的该成员函数,参数时a对象,然后比较分数,比如调用的是a对象的成员函数,且a分数高于b,即要返回a对象,那么return谁呢?这里就有一点问题了,因此c++提供了this指针,在成员函数中,this指向本对象,谁调用的成员函数,就指向谁。
上述实例中,某个成员函数中
scores 与this->scores是等价的
因此,要返回该对象,使用 *this即可:
//class.cpp中函数定义
const Student & Student::max_(const Student& t) const {
if (this->scores > t.scores)
return *this;
else
return t;
}
这里需要注意,Student表示返回值为Student 引用,即返回本身,不会返回副本,提高效率,名称中最后的const表示this指针不会修改西私有变量,这一点需要注意:
如果有多个对象,可以利用对象数组:
Student stu[5]{
Student(...),
Student(...),
Student(...),
Student(...),
Student(...)
};
使用方法与正常数组方法相同。
最后一点,在类中定义常量:
class Student{
private:
const int SIZE = 5;
...
}
本意是定义一个常量,但是行不通的,声明类只是描述了声明对象的形式,并没有创建对象。所以在定义对象前,没有内存空间,无法定义常量。
有另外两种方式:
1.利用枚举类型:
class Student{
private:
enum {Months = 5}
...
}
2.利用static声明静态变量:
class Student{
private:
static const int SIZE = 5;
...
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)