每日三百行代码 第十九天

定义结构

struct type_name {
   
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

type_name 是结构体类型的名称,member_type1 member_name1 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在结构定义的末尾,最后一个分号之前,您可以指定一个或多个结构变量,这是可选的。下面是声明一个结构体类型 Books,变量为 book:

struct Books
{
   
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

访问结构成员

为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。

#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
   Books Book2;        // 定义结构体类型 Books 的变量 Book2
 
   // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "eternity"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "eternity");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;
 
   // 输出 Book1 信息
   cout << "第一本书标题 : " << Book1.title <<endl;
   cout << "第一本书作者 : " << Book1.author <<endl;
   cout << "第一本书类目 : " << Book1.subject <<endl;
   cout << "第一本书 ID : " << Book1.book_id <<endl;
 
   // 输出 Book2 信息
   cout << "第二本书标题 : " << Book2.title <<endl;
   cout << "第二本书作者 : " << Book2.author <<endl;
   cout << "第二本书类目 : " << Book2.subject <<endl;
   cout << "第二本书 ID : " << Book2.book_id <<endl;
 
   return 0;
}
第一本书标题 : C++ 教程
第一本书作者 : eternity
第一本书类目 : 编程语言
第一本书 ID : 12345
第二本书标题 : CSS 教程
第二本书作者 : eternity
第二本书类目 : 前端技术
第二本书 ID : 12346

结构作为函数参数

#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
   Books Book2;        // 定义结构体类型 Books 的变量 Book2
 
    // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "eternity"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "eternity");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;
 
   // 输出 Book1 信息
   printBook( Book1 );
 
   // 输出 Book2 信息
   printBook( Book2 );
 
   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;
}
当上面的代码被编译和执行时,它会产生下列结果:

书标题 : C++ 教程
书作者 : eternity
书类目 : 编程语言
书 ID : 12345
书标题 : CSS 教程
书作者 : eternity
书类目 : 前端技术
书 ID : 12346

指向结构的指针

您可以定义指向结构的指针,
方式与定义指向其他类型变量的指针相似,
如下所示:
struct Books *struct_pointer;

现在,您可以在上述定义的指针变量中存储结构变量的地址。
为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,
如下所示:
struct_pointer = &Book1;

为了使用指向该结构的指针访问结构的成员,
您必须使用 -> 运算符,如下所示:
struct_pointer->title;
#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
   Books Book2;        // 定义结构体类型 Books 的变量 Book2
 
    // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "eternity"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "eternity");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;
 
   // 通过传 Book1 的地址来输出 Book1 信息
   printBook( &Book1 );
 
   // 通过传 Book2 的地址来输出 Book2 信息
   printBook( &Book2 );
 
   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;
}
当上面的代码被编译和执行时,它会产生下列结果:

书标题  : C++ 教程
书作者 : eternity
书类目 : 编程语言
书 ID : 12345
书标题  : CSS 教程
书作者 : eternity
书类目 : 前端技术
书 ID : 12346

typedef 关键字

typedef struct Books
{
   
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Books;

现在,您可以直接使用 Books 来定义 Books 类型的变量,
而不需要使用 struct 关键字。下面是实例:
Books Book1, Book2;

C++ 类定义
定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。例如,我们使用关键字 class 定义 Box 数据类型,如下所示:

class Box
{
   
   public:
      double length;   // 盒子的长度
      double breadth;  // 盒子的宽度
      double height;   // 盒子的高度
};
关键字 public 确定了类成员的访问属性。
在类对象作用域内,公共成员在类的外部是可访问的。
您也可以指定类的成员为 privateprotected,
这个我们稍后会进行讲解。

访问数据成员
类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问。

#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;
}
int main( )
{
   
   Box Box1;        // 声明 Box1,类型为 Box
   Box Box2;        // 声明 Box2,类型为 Box
   Box Box3;        // 声明 Box3,类型为 Box
   double volume = 0.0;     // 用于存储体积
 
   // box 1 详述
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;
 
   // box 2 详述
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
 
   // box 1 的体积
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Box1 的体积:" << volume <<endl;
 
   // box 2 的体积
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Box2 的体积:" << volume <<endl;
 
 
   // box 3 详述
   Box3.set(16.0, 8.0, 12.0); 
   volume = Box3.get(); 
   cout << "Box3 的体积:" << volume <<endl;
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Box1 的体积:210
Box2 的体积:1560
Box3 的体积:1536

C++ 类成员函数

让我们看看之前定义的类 Box,
现在我们要使用成员函数来访问类的成员,
而不是直接访问这些类的成员:
class Box
{
   
   public:
      double length;         // 长度
      double breadth;        // 宽度
      double height;         // 高度
      double getVolume(void);// 返回体积
};
成员函数可以定义在类定义内部,
或者单独使用范围解析运算符 :: 来定义。
在类定义中定义的成员函数把函数声明为内联的,
即便没有使用 inline 标识符。
所以您可以按照如下方式定义 getVolume() 函数:
class Box
{
   
   public:
      double length;      // 长度
      double breadth;     // 宽度
      double height;      // 高度
   
      double getVolume(void)
      {
   
         return length * breadth * height;
      }
};
您也可以在类的外部使用范围解析运算符 :: 定义该函数,
如下所示:
double Box::getVolume(void)
{
   
    return length * breadth * height;
}
需要强调一点,在 :: 运算符之前必须使用类名。
调用成员函数是在对象上使用点运算符(.),
这样它就能操作与该对象相关的数据,如下所示:
Box myBox;          // 创建一个对象
 
myBox.getVolume();  // 调用该对象的成员函数
#include <iostream>
 
using namespace std;
 
class Box
{
   
   public:
      double length;         // 长度
      double breadth;        // 宽度
      double height;         // 高度
 
      // 成员函数声明
      double getVolume(void);
      void setLength( double len );
      void setBreadth( double bre );
      void setHeight( double hei );
};
 
// 成员函数定义
double Box::getVolume(void)
{
   
    return length * breadth * height;
}
 
void Box::setLength( double len )
{
   
    length = len;
}
 
void Box::setBreadth( double bre )
{
   
    breadth = bre;
}
 
void Box::setHeight( double hei )
{
   
    height = hei;
}
 
// 程序的主函数
int main( )
{
   
   Box Box1;                // 声明 Box1,类型为 Box
   Box Box2;                // 声明 Box2,类型为 Box
   double volume = 0.0;     // 用于存储体积
 
   // box 1 详述
   Box1.setLength(6.0); 
   Box1.setBreadth(7.0); 
   Box1.setHeight(5.0);
 
   // box 2 详述
   Box2.setLength(12.0); 
   Box2.setBreadth(13.0); 
   Box2.setHeight(10.0);
 
   // box 1 的体积
   volume = Box1.getVolume();
   cout << "Box1 的体积:" << volume <<endl;
 
   // box 2 的体积
   volume = Box2.getVolume();
   cout << "Box2 的体积:" << volume <<endl;
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Box1 的体积: 210
Box2 的体积: 1560
一个类可以有多个 publicprotectedprivate 标记区域。
每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。
成员和类的默认访问修饰符是 privateclass Base {
   
    public:
   // 公有成员
    protected:
   // 受保护成员
    private:
   // 私有成员 
};

公有(public)成员

#include <iostream>
 
using namespace std;
 
class Line
{
   
   public:
      double length;
      void setLength( double len );
      double getLength( void );
};
 
// 成员函数定义
double Line::getLength(void)
{
   
    return length ;
}
 
void Line::setLength( double len )
{
   
    length = len;
}
 
// 程序的主函数
int main( )
{
   
   Line line;
 
   // 设置长度
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   // 不使用成员函数设置长度
   line.length = 10.0; // OK: 因为 length 是公有的
   cout << "Length of line : " << line.length <<endl;
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Length of line : 6
Length of line : 10

私有(private)成员

私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。
只有类和友元函数可以访问私有成员。

默认情况下,类的所有成员都是私有的。
例如在下面的类中,width 是一个私有成员,
这意味着,如果您没有使用任何访问修饰符,
类的成员将被假定为私有成员:

实例
class Box
{
   
   double width;
   public:
      double length;
      void setWidth( double wid );
      double getWidth( void );
};
#include <iostream>
 
using namespace std;
 
class Box
{
   
   public:
      double length;
      void setWidth( double wid );
      double getWidth( void );
 
   private:
      double width;
};
 
// 成员函数定义
double Box::getWidth(void)
{
   
    return width ;
}
 
void Box::setWidth( double wid )
{
   
    width = wid;
}
 
// 程序的主函数
int main( )
{
   
   Box box;
 
   // 不使用成员函数设置长度
   box.length = 10.0; // OK: 因为 length 是公有的
   cout << "Length of box : " << box.length <<endl;
 
   // 不使用成员函数设置宽度
   // box.width = 10.0; // Error: 因为 width 是私有的
   box.setWidth(10.0);  // 使用成员函数设置宽度
   cout << "Width of box : " << box.getWidth() <<endl;
 
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Length of box : 10
Width of box : 10

protected(受保护)成员

protected(受保护)成员变量或函数与私有成员十分相似,
但有一点不同,
protected(受保护)成员在派生类(即子类)中是可访问的。

在下一个章节中,您将学习到派生类和继承的知识。
现在您可以看到下面的实例中,
我们从父类 Box 派生了一个子类 smallBox。
#include <iostream>
using namespace std;
 
class Box
{
   
   protected:
      double width;
};
 
class SmallBox:Box // SmallBox 是派生类
{
   
   public:
      void setSmallWidth( double wid );
      double getSmallWidth( void );
};
 
// 子类的成员函数
double SmallBox::getSmallWidth(void)
{
   
    return width ;
}
 
void SmallBox::setSmallWidth( double wid )
{
   
    width = wid;
}
 
// 程序的主函数
int main( )
{
   
   SmallBox box;
 
   // 使用成员函数设置宽度
   box.setSmallWidth(5.0);
   cout << "Width of box : "<< box.getSmallWidth() << endl;
 
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

Width of box : 5