C++从入门到放弃
类和对象
1. 类和对象的基本认识
- 什么是对象
万物皆是对象,任何一种事物都可以看做时对象 - 如何描述对象
通过对象的属性和行为来描述对象 - 面向对象的程序设计
对自然界中的对象观察引入到编程实践的一种理念和方法,这种方法被称为"数据抽象",即在描述对象时把细节东西剥离出去,只考虑一般性的,有规律的和统一性的东西 - 什么是类
类是将多个对象的共同性提取出来定义的一种新的数据类型,是对对象属性的行为的抽象描述
2. 类的定义和实例化
- 类的一般语法形式
struct/class 类名:继承方式 基类,...{
访问控制限定符:
类名(形参表):初始化列表{...} //构造函数
~类名(void){...} //析构函数
返回值类型 函数名(形参表){...} //成员函数
数据类型 m_变量名;//成员函数
};
- 访问控制限定符
public
公有成员: 在任何位置都可以访问,类的内部和外部都可以访问private
私有成员: 只有类的内部成员才可以访问,不可以通过类的对象直接访问,可以通过类的公有成员函数来访问私有成员变量或者私有成员函数
在继承特性中,基类的私有成员对于派生类(子类)成员和友元是不能访问的protected
保护成员只有类的内部成员才可以访问,不能通过类的对象直接访问,可以通过公有成员函数来访问私有成员变量或者私有成员函数
在继承特性中,基类的保护成员对于派生类成员和友元是可以访问的
默认访问属性
struct
定义的类 默认的访问属性是public
class
定义的类 默认的访问属性是private
Code
#include <iostream>
using namespace std;
//定义一个描述学生对象的属性和行为
//行为:成员函数
//属性:成员数量
class Student{
public:
/* 类中的私有成员在外部不能访问,但是可以提供
* 类似如下形式的公有成员函数来间接访问,在
* 函数体中可以对非法加以限定控制业务逻辑的
* 合理性,这种编程方法就是封装特性*/
//行为
//行为一
void eat(const string& food){
cout << "我在吃" << food <<endl;
}
//行为二
void sleep(int hour){
cout << "我睡了" << hour << "小时" << endl;
}
//行为三
void learn(const string& course){
cout << "我在学" << course << endl;
}
//行为四
void who(void){
cout << "我叫" << m_name << " ,今年" << m_age << "岁,学号是" << m_no << endl;
}
public:
void setName(const string& newName){
if(newName == "二")
cout << "你才二" << endl;
else
m_name = newName;
}
void setAge(int newAge){
if(newAge <= 0)
cout << "无效年龄" << endl;
else
m_age = newAge;
}
void setNo(int newNo){
if(newNo < 0 )
cout << "无效学号" << endl;
else
m_no = newNo;
}
private:
//属性
string m_name;//姓名
int m_age;//年龄
int m_no;//学号
};
int main(void){
//创建对象,实例化对象,构造对象
Student stu;
/* stu.m_name = "张飞";
stu.m_age = 25;
stu.m_no = 10011;
stu.who();*/
stu.setName("二");
stu.setName("张翼德");
stu.setAge(0);
stu.setAge(26);
stu.setNo(-1);
stu.setNo(10012);
stu.who();
stu.eat("牛肉拉面");
stu.sleep(6);
stu.learn("面向对象编程");
return 0;
}
#include <iostream>
using namespace std;
class Stu{
public:
Stu(){
cout << "构造函数"<<endl;
}
Stu(string &name, int age,int no):m_name(name),m_age(age),m_no(no){
cout<<"自定义构造"<<endl;
}
void who(){
cout<<"我是"<<m_name<<",今年"<<m_age<<"岁"<<", 学号是:"<<m_no<<endl;
}
void setName(string& name){
m_name = name;
}
private:
string m_name;
int m_age;
int m_no;
};
int main() {
string name;
name = "lisi";
Stu s1(name,20,10010);
s1.who();
name = "李四";
s1.setName(name);
s1.who();
}
3. 对象的创建和销毁
- 在栈区创建单个对象
类名 对象(构造实参表);//创建对象,调用有参构造函数直接初始化
类名 对象 = 类名(构造实参表);//拷贝初始化,编译器执行时会优化成上面那种,实际效果是等价的
类名 = 单个构造实参;//单参数为一个时,等价拷贝初始化
- 在栈区创建对象数组
类名 对象数组[元素个数] = {类名(构造实参表),...};
- 在堆区创建/销毁单个对象(动态创建对象)
//创建
类名 *对象指针 = new 类名(构造实参表);
//new操作符分配内存后会自动调用构造函数,完成对象的创建和初始化;而如果是malloc只会分配内存,不会调用构造函数,不具备创建对象的能力.
//销毁
delete 对象指针;
//delete会在delete对象时调用对象的析构函数
- 在堆区创建/销毁对象数组
//创建
类名 *对象指针 = new 类名[元素个数]{类名(构造实参表),...}
//销毁
delete[] 对象指针;
对象指针 = NULL;
//调用delete[] 会自动调用数组中每个对象自己的析构函数,有几个实例化对象就会调用几次析构函数