一、类和数据抽象
面向对象的思想就是将任何事物看作对象,对象有自己的属性和行为,收集这些属性就是数据抽象的任务。
-
用类实现数据的抽象
public:成员可以被类外访问。
private:成员只能在类内访问。
protected:可以被类内和该类的子类访问。
-
构造函数:与类同名的函数,作用:在对象生成的时候,初始化成员数据。
-
析构函数:~ 作用:在对象结束时清理对象的成员数据,释放动态内存分配。
-
const对象和const成员函数
作用:声明常量型的变量,修改const类型的数据将引起编译错误。
-
friend对象和friend类
friend 友元。类的friend函数可以访问类的private成员。定义的友元函数需要在类的定义中说明。
友元函数引用的参数就是类的地址,通过类的地址就可以访问类内的成员。
friend void good(Buddy *b); good(&b); friend void good(Buddy &b); good(b); friend class class2;//类作为友元,可以访问class1中的成员。
-
this 指针
类定义中指向自己的指针,this指针只有在成员函数中才有定义。this指针不能在静态函数中使用
-
动态内存分配
C 语言:malloc() 首先申请一片连续的内存空间,返回指向这片内存空间的指针,需要判断函数返回值是否为NULL。
int *p = malloc(sizeof(int)); if(P!= NULL){ } free(p);
C++:new
类型名 * 指针 = new 类型名; int * p = new int(size); delete p;
new返回有类型的指针,malloc返回无类型的指针。
-
static类成员
static:用来定义静态数据类型,如果类的数据定义位static类型,那么该类生成的所有对象将使用同一个内存空间保存该成员的数据。
二、C++特性 :封装 、继承、多态
封装:实现代码的模块化
封装类的访问类型:public private protected(成员只能被该类的成员函数或派生类的成员函数访问)
继承:实现代码扩展
多态:虚函数,函数重载
通过基类的对象指针或引用访问虚函数
-
运算符重载 : 实现2个字符串的叠加
#include <iostream> #include <string> #pragma warning(disable:4996) using namespace std; class String { public: String(const char *str ); //构造函数 char * m_data; char * m_addstr; String operator +(const String& rh); }; String::String(const char* str ) { if (str == NULL) { m_data = new char[1]; m_data[0] = '\0'; } else { m_data = new char[strlen(str)+1]; strcpy(m_data,str); } } String String::operator +(const String &rhs) { m_addstr = new char[strlen(m_data) + strlen(rhs.m_data) + 1]; strcpy(m_addstr,m_data); strcat(m_addstr,rhs.m_data); delete m_data; m_data = new char[strlen(m_addstr) + 1]; strcpy(m_data, m_addstr); delete m_addstr; return *this; } int main() { String s1("wwww"); String s2("eeee"); s1 + s2; puts(s1.m_data); return 0; }
strcpy()函数重载:
char *strcpy(char *dest, const char *src); // 将字符串src 复制到 数组dest中。 返回值:返回参数dest 的字符串起始地址。
strcpy函数 没有对dest数组进行初始化, 如果字符串长度超过dest,会造成内存溢出。
//size_t: size_t是全局定义的类型;数组下标的正确类型则是size_t
//size_type: 是STL类中定义的类型属性,用以保存任意string和vector类对象的长度.
strcpy函数重载:
char *strcpy(char *dest,const char *src,size_t destsize) {
///数组初始化
memset(dest,0,destsize);
size_t len = 0;
计算需要复制的字符串长度
if(strlen(src) <= destsize-1) len =strlen(src);
else len = destsize-1;
strcpy(dest,src,len); //复制字符串多出去的丢掉。
dest[len] = 0; //强制字符串结尾
return dest;
}
-
继承
利用一个类生成另一个类的对象。子类获得父类所有成员,此外还有自己的成员。
class father{ }; class son :public father { };
#include <iostream> #include <string> using namespace std; class Father { public: void set_value(int a, int b) { height = a; width = b; } protected: int height; int width; }; class Son : public Father { public: int area() { return height * width; } }; int main() { Son s1; Father F; s1.set_value(4,5); cout<<s1.area(); return 0; }
-
虚拟函数和多态性
虚拟函数: 在父类中定义但不实现,在子类中进行实现。虚拟函数必须加上virtual,通过父类的指针调用实际子类的成员函数。
主要是为了实现一个接口,规范继承。
纯虚函数:virtual void funtion1()=0。
当基类指针指向一个子类对象,通过这个指针调用子类和基类同名成员函数的时候,基类声明为虚函数「子类不写也可以」就会调子类的这个函数,不声明就会调用基类的。
#include <iostream> #include <string> using namespace std; class Father { public: void set_value(int a, int b) { height = a; width = b; } virtual int area() { return height * width / 2; } protected: int height; int width; }; class Son : public Father { public: int area() { return height * width; } }; class Son1 : public Father { public: int area() { return height * width; } }; int main() { Son1 s1; Father *F = new Son1; F->set_value(4,5); cout<<F->area(); return 0; }
多态 :通过虚拟函数进行实现,即通过同一个父类的虚拟函数,子类实现不同的功能。
-
模板
利用模板,不仅可以指定全部相关的函数重载。还可以指定全部的类