《C++程序设计》笔记p2
类(class)和对象(object)
int 是类 100、0、-2 是真实存在的对象/------- 100
int < -------- 0 \-------- -2float 是类. 3.14、2.718. 是对象C 语言中已经定义号的基础类:整数: char、short int、int、long int、long long int;小数: float、double、long double。自定义类型 Car
struct Car{string brand; // 品牌string Number; // 车牌号string color; // 颜色void run(float speed) {}
};Car car1, car2 // 创建 Car 类型的对象car1, car2
C++类中的成员:
成员函数和成员变量
**属性:**用于保存一个对象的数据。C++ 用成员变量来存储
**行为:**用于描述一个对象的动作;C++ 用成员函数来实现
struct Human{string name;string gender;int age;float height;void eat (string food) {};void walk(float km) {}int study(string subject){} // 学习
}
类(class)
作用:创建一个自定义的类型,同C语言中的结构体。
语法:
class 类名 {//访问说明符public:protected:private:成员变量定义成员函数定义
};
说明:
- 类名必须是一个标识符。按编码规范,类名都使用单词首字母大写的标识符(即大驼峰命名法)
- 类的定义的语法后必须加分号(
;
)(和结构体相同)。 - 访问说明符用户控制类内成员的访问权限。有三种:
public
表示类内成员函数和非成员函数都可以访问。protected
表示类内成员函数和子类成员函数可以访问,非成员函数不可以访问。private
表示类内成员函数可以访问,子类成员函数和非成员函数不可以访问。
- 成员函数可以定义在类内和类的外部。
- 类和C++结构体的区别
- 类的成员(变量或函数)默认的访问权限是私有(private)。
- 结构体的成员(变量或函数)默认的访问权限是共有(public)。
成员变量:
同C 语言的结构体成员变量相同。
成员函数:
是定义在类内的函数,名字空间属于类,需要使用该类的对象来调用。
调用语法:
对象.成员函数名(实际参数列表...)
说明:
- 成员函数同 C 语言的函数一样,可以有参数和返回值。
- 成员函数的调用是一个表达式(同C语言)。
- 按习惯,C语言的成员函数一般使用驼峰命名法(建议使用小驼峰)。
示例:
#include <iostream>using namespace std;// 定义一个矩形类(长方形类),此类可以设置长和宽,
// 同时可以返回矩形的面积和周长
class Rectangle {public:int width;int height;void set_width_height(int w, int h) {width = w, height = h;}int get_area(void) {return width * height;}int get_length(void) {return (width + height) * 2;}
};int main(int argc, char * argv[]) {Rectangle r1;r1.set_width_height(10, 2);cout << "r1的周长:" << r1.get_length() << endl;cout << "r1的面积:" << r1.get_area() << endl;// cout << get_length() << endl; // 报错return 0;
}
C 语言的写法参考
#include <iostream>using namespace std;// 定义一个矩形类(长方形类),此类可以设置长和宽,
// 同时可以返回矩形的面积和周长
struct rectangle {int width;int height;
};
void set_width_height(struct rectangle * r, int w, int h) {r->width = w, r->height = h;
}
int get_area(struct rectangle * r) {return r->width * r->height;
}
int get_length(struct rectangle * r) {return (r->width + r->height) * 2;
}
/*
class Rectangle {public:int width;int height;void set_width_height(int w, int h) {width = w, height = h;}int get_area(void) {return width * height;}int get_length(void) {return (width + height) * 2;}
};*/int main(int argc, char * argv[]) {struct rectangle r1;// r1.set_width_height(10, 2);set_width_height(&r1, 10, 2);cout << "r1的周长:" << get_length(&r1) << endl;cout << "r1的面积:" << get_area(&r1) << endl;// cout << get_length() << endl; // 报错return 0;
}
this 指针
this 指针是 C++ 成员函数内,指向调用对象地址的指针。
作用:通常用来明确指示某个标识符是成员变量还是局部变量。
说明:
C++
的每个成员函数都有一个this指针指向调用此函数的对象(默认成员函数的第一个参数就是this指针,只不过CPP的语法隐藏了this指针(第一个参数));
用this改写后示例
#include <iostream>
#include <stdio.h>using namespace std;// 定义一个矩形类(长方形类),此类可以设置长和宽,
// 同时可以返回矩形的面积和周长
class Rectangle {public:int width;int height;void set_width_height(int width, int h) {printf("this->%p\n", this);this->width = width, height = h;}int get_area(void) {return width * height;}int get_length(void) {return (width + height) * 2;}
};int main(int argc, char * argv[]) {Rectangle r1;Rectangle r2;printf("&r1:%p\n", &r1);printf("&r2:%p\n", &r2);r1.set_width_height(10, 2);r2.set_width_height(100, 200);cout << "r1的周长:" << r1.get_length() << endl;cout << "r1的面积:" << r1.get_area() << endl;// cout << get_length() << endl; // 报错return 0;
}
特殊成员函数
构造函数(Constructor Function)
作用:用于对新创建的对象的成员变量进行初始化。
语法:
class 类名:
{public:类名(形参列表) : 成员变量的初始化列表 {}类型 成员变量1;类型 成员变量2;
};
说明:
- 默认一个对象在创建时都一定会调用构造函数。
- 构造函数的函数名必须是类名。
- 每个类内默认都有一个无参的构造函数。类的实现中如果有定义构造函数,则无参的构造函数失效。
- 构造函数可以重载,默认会根据实参列表调用相应的构造函数。
- 构造函数不需要有返回类型和返回值。
- C++的对象先创建,然后才调用构造函数进行初始化。
- 成员变量的初始化列表用来显式调用对象成员的构造函数,否则默认会调用成员变量无参的构造函数。
示例:
#include <iostream>
#include <stdio.h>using namespace std;// 定义一个矩形类(长方形类),此类可以设置长和宽,
// 同时可以返回矩形的面积和周长
class Rectangle {private:int width;int height;public:// 无参数的构造函数Rectangle(void):width(0),height(0) {cout << "无参的构造函数被调用" << endl;}// Rectangle(void) { // 无参数的构造函数// cout << "无参的构造函数被调用" << endl;// this->width = 0; height = 0;// }// 带有参数的构造函数Rectangle(int width, int height=1) {cout << "带有参数的构造函数被调用" << endl;this->width = width; this->height = height;}void set_width_height(int width, int h) {printf("this->%p\n", this);if (width < 0) return;if (h < 0) return;this->width = width, height = h;}int get_area(void) {return width * height;}int get_length(void) {return (width + height) * 2;}
};int main(int argc, char * argv[]) {Rectangle r1; // r1.width, r1.heightRectangle r2(100, 10);int i1;int i2(99);cout << "===============" << endl;cout << i1 << endl;cout << i2 << endl;// r1.set_width_height(10, 2);cout << "r1的周长:" << r1.get_length() << endl;cout << "r1的面积:" << r1.get_area() << endl;cout << "r2的周长:" << r2.get_length() << endl;cout << "r2的面积:" << r2.get_area() << endl;return 0;
}
构造函数的初始化列表示例
// #include <stdio.h>
#include <iostream>using namespace std;class Man{public:Man(string n = "No Name"): name(n) {cout << "男人的构造函数已经被调用, name:" << name << endl;}string name;
};class Woman{public:Woman(string n = "No Name"): name(n) {cout << "女人的构造函数已经被调用, name:" << name << endl;}string name;
};
class Family {public:Family(string manName, string womanName):// 显示调用m和w的构造函数来代替无参的构造函数m(manName), w(womanName){// m.name = manName;// w.name = womanName;}void showInfo(void) {cout << "Fimaly(" << m.name << ", " << w.name << ")\n";}Man m;Woman w;
};int main(int argc, char * argv[]) {Family f("张三", "小凤");f.showInfo();return 0;
}
示例使用 C++ 封装一个栈类型。用于描述一个栈。
#include <stdio.h>class Stack {private:int data[20]; // 用来保存数据int top; // 用来记录栈顶的位置public:Stack(void) { } // 初始化栈void clear(void) { } // 清空栈// 判断栈空, 栈为空返回 true, 否则返回falsebool isEmpty(void) {}// 判断栈满 栈为满返回 true, 否则返回flasebool isFull(void) {}// 获取栈顶元素,成功返回1,数据放入pvalue指向的变量,失败返回0bool topValue(int &value) { }// 获取栈元素个数int getValueCount() { }// 入栈:成功返回true,失败返回flasebool stackPush(int &value) { }// 出栈:成功返回true,数据放入value指向的变量bool pop(int &value) { }
};int main(int argc, char * argv[]) {Stack stk; // 定义一个栈return 0;
}
C语言实现参考
#include <stdio.h>struct stack {int data[20]; // 用来保存数据int top; // 用来记录栈顶的位置
};
// 初始化栈
void stack_init(struct stack * pstk) {pstk->top = 0;
}
// 清空栈
void stack_clear(struct stack * pstk) {stack_init(pstk);
}
// 判断栈空, 栈为空返回 1, 否则返回0
int stack_is_empty(struct stack * pstk) {return pstk->top == 0;
}
// 判断栈满 栈为满返回 1, 否则返回0
int stack_is_full(struct stack * pstk) {return pstk->top == sizeof(pstk->data) / sizeof(pstk->data[0]);
}
// 获取栈顶元素,成功返回1,数据放入pvalue指向的变量,失败返回0
int stack_top_value(struct stack * pstk, int * pvalue) {if (pstk->top == 0)return 0;*pvalue = pstk->data[pstk->top-1];return 1;
}
// 获取栈元素个数
int stack_get_value_count(struct stack *pstk) {return pstk->top;
}
// 入栈:成功返回1,失败返回0
int stack_push(struct stack *pstk, int value) {if (stack_is_full(pstk))return 0;pstk->data[pstk->top] = value;pstk->top++;
}
// 出栈:成功返回1,数据放入pvalue指向的变量
int stack_pop(struct stack * pstk, int * pvalue) {if (stack_is_empty(pstk))return 0;pstk->top--;*pvalue = pstk->data[pstk->top];return 1;
}int main(int argc, char * argv[]) {struct stack stk; // 定义一个栈if (stk.top == 0) return 0;
}
参考答案:
#include <iostream>
#include <stdio.h>using namespace std;
class Stack {private:int data[20]; // 用来保存数据int top; // 用来记录栈顶的位置public:Stack(void):top(0){ } // 初始化栈void clear(void) { top = 0; } // 清空栈// 判断栈空, 栈为空返回 true, 否则返回falsebool isEmpty(void) {return top == 0;}// 判断栈满 栈为满返回 true, 否则返回flasebool isFull(void) {return top >= sizeof(data)/sizeof(data[0]);}// 获取栈顶元素,成功返回1,数据放入pvalue指向的变量,失败返回0bool topValue(int &value) {if (!top)return false;value = data[top-1];return true;}// 获取栈元素个数int getValueCount() {return top; }// 入栈:成功返回true,失败返回flasebool stackPush(const int &value) {if (isFull())return false;data[top] = value;top++; return true;}// 出栈:成功返回true,数据放入value指向的变量bool pop(int &value) {if (isEmpty()) return false;value = data[top-1];top--;return true;}
};int main(int argc, char * argv[]) {Stack stk; // 定义一个栈stk.stackPush(100);stk.stackPush(200);stk.stackPush(300);int v;stk.pop(v);cout << "v:" << v << endl;cout << "count:" << stk.getValueCount() << endl;return 0;
}
成员函数的类内声明和类外实现
语法:
class 类名 {返回类型 成员函数名(参数列表) {...}
};
拆分成声明部分
class 类名 {返回类型 成员函数名(参数列表);
};
实现部分
返回类型 类名::成员函数名(参数列表) {
}
示例代码:
#include <iostream>
#include <stdio.h>using namespace std;
class Stack {private:int data[20]; // 用来保存数据int top; // 用来记录栈顶的位置public:Stack(void); // 初始化栈void clear(void); // 清空栈// 判断栈空, 栈为空返回 true, 否则返回falsebool isEmpty(void); // 判断栈满 栈为满返回 true, 否则返回flasebool isFull(void); // 获取栈顶元素,成功返回1,数据放入pvalue指向的变量,失败返回0bool topValue(int &value);// 获取栈元素个数int getValueCount(); // 入栈:成功返回true,失败返回flasebool stackPush(const int &value);// 出栈:成功返回true,数据放入value指向的变量bool pop(int &value);
};
Stack::Stack(void):top(0){ } // 初始化栈
void Stack::clear(void) { top = 0; } // 清空栈
// 判断栈空, 栈为空返回 true, 否则返回false
bool Stack::isEmpty(void) {return top == 0;}
// 判断栈满 栈为满返回 true, 否则返回flase
bool Stack::isFull(void) {return top >= sizeof(data)/sizeof(data[0]);
}
// 获取栈顶元素,成功返回1,数据放入pvalue指向的变量,失败返回0
bool Stack::topValue(int &value) {if (!top)return false;value = data[top-1];return true;
}
// 获取栈元素个数
int Stack::getValueCount() {return top; }
// 入栈:成功返回true,失败返回flase
bool Stack::stackPush(const int &value) {if (isFull())return false;data[top] = value;top++; return true;
}
// 出栈:成功返回true,数据放入value指向的变量
bool Stack::pop(int &value) {if (isEmpty()) return false;value = data[top-1];top--;return true;
}int main(int argc, char * argv[]) {Stack stk; // 定义一个栈stk.stackPush(100);stk.stackPush(200);stk.stackPush(300);int v;stk.pop(v);cout << "v:" << v << endl;cout << "count:" << stk.getValueCount() << endl;return 0;
}