提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目
先建立一个Point(点)类,包括private类型数据成员x、y(坐标点)。以他为基类,派生出Circle(圆)类,增加数据成员r(半径)。再以Circle为直接基类,派生出Cylinder(圆柱体)类,再增加数据成员h(高度)。重载运算符“>>”和“<<”,使之能够输出以上类对象。
一、概念介绍
1.private类型是什么
当你在C++中创建一个类(就像是一个新的数据类型),你可以决定哪些东西可以被外面的人看到和使用,哪些只能在类的内部被处理。private 就是一种“保密”标签,用来把一些东西藏起来,不让外面的人直接碰。
想象一下,你有一个玩具盒子,里面有你最珍贵的玩具。你不想让别人拿走或损坏它们,所以你把盒子上了锁,只有你能打开盒子,然后拿出玩具玩。在这里,盒子就是类,玩具就是类的数据,而锁就是 private。只有在类的“内部”,也就是在类的代码里,你才能够使用这些被标记为 private 的东西。其他人无法直接触碰这些东西。
所以,private 数据成员就是那些只能在类的内部使用的数据。外面的人不能直接改变它们的值,只有类的内部函数才能够操作这些数据。这样做可以保护数据,确保它们不会被意外地修改。
2.继承是什么
当我们在编程中谈论继承时,就好像我们在谈论家族中的传承一样。想象一下,你是一个家族的一员,你继承了你父母的一些特征和财产。在编程中,继承也是类似的概念,允许你创建一个新的类,这个新类可以继承另一个已经存在的类的特征和行为。
在继承中,有两个关键角色:基类(也叫父类或超类)和派生类(也叫子类)。基类是已经存在的类,它有一些属性和方法。派生类是你从基类创建的新类,你可以在派生类中添加自己的属性和方法,同时也继承了基类的属性和方法。
想象你有一个基类叫做 “动物”,它有一些通用的属性和方法,比如 “吃” 和 “睡觉”。现在你想创建一个派生类叫做 “狗”,你可以从 “动物” 这个基类继承 “吃” 和 “睡觉” 这些通用的特征,同时你还可以在 “狗” 类中添加一些特有的特征,比如 “叫” 和 “追赶小球”。
继承的好处在于可以节省代码,因为你不必为每个类都写相同的代码,而是可以共享基类的代码。另外,它也能帮助你组织类的层次结构,使代码更加有组织和易于维护。
3.如何重载输入输出运算符
重载输入输出运算符就像是告诉计算机怎么样读取和显示你自定义的类对象。你可以想象一下,如果你有一个特殊的类,表示一本书,你希望能够方便地输入书的信息并将其显示出来,这时你可以通过重载输入输出运算符来实现。
在C++中,<< 和 >> 是用于输出和输入的运算符。当你重载这些运算符,实际上是在告诉编译器如何处理你的类对象。
让我们以一个示例来说明。假设你有一个表示书的类 Book,其中包含书的标题和作者。你希望能够使用 << 运算符来显示书的信息,并使用 >> 运算符从用户那里输入书的信息。你可以这样定义重载:
#include <iostream>
#include <string>
class Book {
private:
std::string title;
std::string author;
public:
// 构造函数等其他成员的定义
// 重载输出运算符
friend std::ostream& operator<<(std::ostream& os, const Book& book) {
os << "Title: " << book.title << "\nAuthor: " << book.author;
return os;
}
// 重载输入运算符
friend std::istream& operator>>(std::istream& is, Book& book) {
std::cout << "Enter title: ";
std::getline(is, book.title);
std::cout << "Enter author: ";
std::getline(is, book.author);
return is;
}
};
int main() {
Book myBook;
// 输入书的信息
std::cin >> myBook;
// 显示书的信息
std::cout << myBook << std::endl;
return 0;
}
二、难点
既然题目要求私有数据成员只可以被类本身调用,那么如何做到既满足题目要求,又做到在程序中任意调用私有数据成员并完成重载输入输出的操作呢?
首先定义类Point
class Point{
private:
int x;
int y;
}
既然类本身可以调用自己的私有数据成员,那不妨定义公有成员函数
public:
int& getPointx(){return x;}
int& getPointy(){return y;}
特别注意!!
因为重载输入运算符需要对变量本身地址进行操作,此处采用返回引用类型的函数,如果只是int类型而不是int&类型,虽然可以完成重载输出操作,但是无法完成重载输入操作
完整代码如下:
#include<iostream>
using namespace std;
class Point{
private:
int x;
int y;
public:
Point(int a=0,int b=0):x(a),y(b){}
int& getPointx(){return x;}
int& getPointy(){return y;}
friend istream& operator>>(istream& is,Point& t){
is >> t.getPointx() >> t.getPointy();
return is;
}
friend ostream& operator<<(ostream& os,Point& t){
os << " x:" <<t.getPointx() << " y:" << t.getPointy() << endl;
return os;
}
};
class Circle:public Point{
private:
int r;
public:
Circle(int a=0,int b=0,int c=0):Point(a,b),r(c){}
int& getCircler(){return r;}
friend istream& operator>>(istream& is,Circle& t){
is >> t.getPointx() >> t.getPointy() >> t.r;
return is;
}
friend ostream& operator<<(ostream& os,Circle& t){
cout << " x:" << t.getPointx() << " y:" << t.getPointy() << " r:" << t.r <<endl;
return os;
}
};
class Cylinder:public Circle{
private:
int h;
public:
Cylinder(int a=0,int b=0,int c=0,int d=0):Circle(a,b,c),h(d){}
friend istream& operator>>(istream& is,Cylinder& t){
is >> t.getPointx() >> t.getPointy() >> t.getCircler() >> t.h;
return is;
}
friend ostream& operator<<(ostream& os,Cylinder& t){
os << " x:" << t.getPointx() << " y:" << t.getPointy() << " r:" << t.getCircler() << " h:" << t.h <<endl;
return os;
}
};
int main(){
Point point;
Circle circle;
Cylinder cylinder;
cin >> point >> circle >> cylinder;
cout << point << circle << cylinder;
return 0;
};
三、 总结
本题涉及类定义的基本操作、成员变量作用范围的理解、构造函数以及多层继承中的构造函数、友元函数实现输入输出重载、引用类型的妙用,考点十分丰富,建议收藏!