C++数据结构
结构是c++中另一种用户自定义的可用的数据类型,允许用户存储不同类型的数据项。
结构定义: struct语句
struct type_name{
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
}object_names;
type_name是 结构体类型的名称, member_type1 member_name1;是标准的变量定义 object_names可选变量,类似于实列化。
访问结构成员
成员访问运算符 .
#include <iostream>
#include <cstring>
using namespace std;
// 声明一个结构体类型 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// 输出 Book1 信息
cout << "第一本书标题 : " << Book1.title <<endl;
cout << "第一本书作者 : " << Book1.author <<endl;
cout << "第一本书类目 : " << Book1.subject <<endl;
cout << "第一本书 ID : " << Book1.book_id <<endl;
return 0;
}
结构作为函数参数
#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books book );
// 声明一个结构体类型 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// 输出 Book1 信息
printBook( Book1 );
return 0;
}
void printBook( struct Books book )
{
cout << "书标题 : " << book.title <<endl;
cout << "书作者 : " << book.author <<endl;
cout << "书类目 : " << book.subject <<endl;
cout << "书 ID : " << book.book_id <<endl;
}
指向结构的指针
#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books *book );
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// 通过传 Book1 的地址来输出 Book1 信息
printBook( &Book1 );
return 0;
}
// 该函数以结构指针作为参数
void printBook( struct Books *book )
{
cout << "书标题 : " << book->title <<endl; // ->运算符
cout << "书作者 : " << book->author <<endl;
cout << "书类目 : " << book->subject <<endl;
cout << "书 ID : " << book->book_id <<endl;
}
typedef关键字
更简单的定义结构方式
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
}Books;
Books Book1, Book2; // 可以直接使用 Books 来定义 Books 类型的变量,而不需要使用 struct 关键字。
C++面向对象
类的定义
类的定义是以关键字class开头,后面跟类的名称。类的主体包含在花括号中。类定义必须跟着一个分号或一个声明列表
#include <iostream>
using namespace std;
class Box
{
public:
double length;
double breadth;
double height;
double get(void);
void set(double len, double bre, double hei);
};
double Box::get(void)
{
return length*breadth*height
}
void Box::set(double len, double bre, double hei)
{
length = len;
breadth = bre;
height = hei;
}
// 类对象的定义
Box Box1; //定义对象Box1
Box Box2; //定义对象Box2
// 访问数据成员直接使用成员访问符 .
Box1.length
Box1.breadth
Box1.height
Box1.set()
Box1.get()
类成员函数
类的成员函数是指 把定义和原型写在类定义内部的函数。
成员函数可以定义在类定义内部,或者利用范围解析运算符 :: 来定义。
在类定义中定义的成员函数把函数声明为 内联 的。
在类外部使用范围解析符之前必须使用类名。
类访问修饰符
类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected来指定。
class Base
{
public:
// 公有成员
private:
// 私有成员
protected:
// 受保护成员
};
公有(public)成员在程序中类的外部是可访问的。
私有(private)成员 变量或函数在类的外部是不可访问的。只有类或友元函数可以访问私有成员。
受保护(protected)成员 可以在派生类(子类)中被访问。
继承的特点:
public继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private
private继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private
protected继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private
类的构造函数
类的一种特殊的成员函数,在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,不会返回任何类型,也不会返回void。
构造函数可用某些成员变量设置初始值。
#include <iostream>
using namespace std;
class Line
{
public:
void setLength(double len);
double getLength(void);
Line(); // 构造函数
private:
double length;
};
Line::Line(void)
{
cout << "Object is being created" << endl;
}
void Line::setLength(double len)
{
length = len;
}
double Line::getLength(void)
{
return length;
}
int main()
{
Line line;
line.setLength(6.0);
cout << "Length of line :" << line.getLength() << endl;
return 0;
}
带参数的构造函数
构造函数也可以带有参数,在创建对象时就会给对象赋初始值。
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(double len); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line(10.0);
// 获取默认设置的长度
cout << "Length of line : " << line.getLength() <<endl;
// 再次设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
使用初始化列表来初始化字段
Line::Line(double len): length(len)
{
cout << len << endl;
}
C::C(double a, double b, double c): X(a), Y(b), Z(c)
{}
类的析构函数
类的析构函数在每次删除所创建的对象时执行。
析构函数的名称与类的名称完全相同,需要加上~作为前缀,不会返回值,也不能带有任何参数
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数声明
~Line(); // 这是析构函数声明
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
拷贝构造函数
在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。通常用于:
- 通过使用另一个同类型的对象来初始化新创建的对象
- 复制对象把它作为参数传递给函数
- 复制对象,并从函数返回这个对象。
//拷贝构造函数的主体
classname (const classname &obj)
{}
#include <iostream>
using namespace std;
class Line
{
public:
int getlength(void);
Line(int len); // 构造函数
Line(const Line &obj); // 拷贝构造函数
~Line(); // 析构函数
private:
int *ptr;
};
Line::Line(int len)
{
cout << "调用构造函数" << endl;
// 为指针分配内存
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
ptr = new int;
*ptr = *obj.ptr; // 拷贝值
}
Line::~Line(void)
{
cout << "释放内存" << endl;
delete ptr;
}
int Line::getlength(void)
{
return *ptr;
}
vid display(Line obj)
{
cout << "line 大小:" << obj.getlength() << endl;
}
int main()
{
Line line(10);
display(line);
return 0;
}
友元函数
类的友元函数定义在类外部,但有权访问类的所有 私有(private)和受保护(protected)成员。友元函数原型在类的定义中出现但并不是成员函数。
友元可以是一函数(友元函数), 也可以是一个类(友元类)。
声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字friend。
内联函数
利用关键字 inline 声明的函数为内联函数。当一个函数是内联时,编辑器编译时,会把该函数的代码副本放置在每个调用该函数的地方。对内联函数进行修改时,都需要重新编译函数的所有客户端。
内联函数引入的目的是为了解决程序中函数调用的效率问题,即程序在编译器编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而其他函数都是运行时才被替换。本质是利用空间代价换取时间的节省。所以内联函数一般是行数很少的小函数。
c++中this指针
每一个对象都能通过this指针来访问自己的地址。 this指针是所有成员函数的隐含参数。友元函数没有this指针
类的静态成员
利用关键字static将类成员定义为 静态的。静态意味着无论创建多少个类的对象,静态成员都只有一个副本。
静态成员在类的所有对象中是共享的。静态成员的初始化放置在类的定义中,但可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。
类的静态成员函数
函数成员被声明为静态时,可以把函数与类的特定对象独立开来,即静态函数成员在类对象不存在的情况下也能被调用,静态函数只要用类名+范围解析符 :: 就可以访问。
静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
C++继承
继承允许依据一个类来定义另一个类。
当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承一个已有的类的成员即可。这个已有的类为基类,新建的类为派生类。
C++重载运算符和重载函数
C++允许在同一作用域中的某个函数和运算符指定多个定义,即函数重载和运算符重载。
当调用一个重载函数或重载运算符时,编译器通过把所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。这个过程称为重载决策。
函数重载
在同一作用域内,可以声明几个功能类似的同名函数,但这些函数的形式参数(参数个数、类型、顺序)必须不同。
运算符重载
重载运算符是带有特殊名称的函数,函数名由关键字 operator 和其后要重载的运算符号构成。
c++接口 抽象类
接口描述了类的行为和功能,
C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。
如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 “= 0” 来指定的,
设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。