【QIUC】第一卷-C/C++高级(十)- 练习二
问题:
定义一个或多个类,来描述以下需求:
汽车:有多个轮胎,一个发动机,品牌,型号, 价格, 行驶里程。
轮胎:有品牌,尺寸,气压。
发动机:有品牌,型号。
源码:
第一种:
Tires.h
#pragma once
#include <string>
#include <vector>
using namespace std;
class Tires
{
public:
Tires(string brand, int size, int pressure);
string getBrand()const;
int getSize()const;
int getPressure()const;
string descripition()const;
static void inPuttires(vector<Tires>&tires);
private:
string brand;
int size;
int pressure;
};
Tires.cpp
#include <string>
#include <sstream>
#include <iostream>
#include "Tires.h"
using namespace std;
Tires::Tires(string brand, int size, int pressure) {
this->brand = brand;
this->size = size;
this->pressure = pressure;
}
string Tires::getBrand()const {
return brand;
}
int Tires::getSize()const {
return size;
}
int Tires::getPressure()const {
return pressure;
}
string Tires::descripition() const
{
stringstream ret;
ret << "轮胎的品牌:" << brand << " " << "轮胎的尺寸:" << size << " "
<< "轮胎的气压:" << pressure << endl;
return ret.str();
}
void Tires::inPuttires(vector<Tires>& tires)
{
int n = 1;
string brand;
int size;
int pressure;
while (1) {
cout << "请输入第" << n << "个的品牌:(输入0结束)";
cin >> brand;
if (brand == "0") {
break;
}
cout << "请输入第" << n << "个的尺寸:";
cin >> size;
cout << "请输入第" << n << "个的气压:";
cin >> pressure;
Tires tires1(brand, size, pressure);
tires.push_back(tires1);
//tires.push_back(Tires(brand,size,pressure));可以
//tires.push_back(&tires1);错误
n++;
}
}
Engine.h
#pragma once
#include <string>
using namespace std;
class Engine
{
public:
Engine(string brand,string model);
string getBrand()const;
string getModel()const;
private:
string brand;
string model;
};
Engine.cpp
#include "Engine.h"
Engine::Engine(string brand, string model)
{
this->brand = brand;
this->model = model;
}
string Engine::getBrand() const
{
return brand;
}
string Engine::getModel() const
{
return model;
}
Car.h
#pragma once
#include <string>
#include <vector>
#include "Engine.h"
#include "Tires.h"
using namespace std;
class Car
{
public:
Car(string brand,string model,int price,unsigned int distance,string engBrand,string ensModel);
string getBrand()const;
string getMoedl()const;
int getPrice()const;
unsigned int getDistance()const;
vector<Tires*> getTires()const;
string descripition()const;
void addTires(Tires &other);
private:
string brand;
string model;
int price;
unsigned int distance;
Engine *engine;
vector<Tires*>tires;
};
Car.cpp
#include <string>
#include <vector>
#include <sstream>
#include "Car.h"
using namespace std;
Car::Car(string brand, string model, int price, unsigned int distance,string engBrand, string ensModel) {
this->brand = brand;
this->model = model;
this->price = price;
this->distance = distance;
this->engine = new Engine(engBrand, ensModel);
}
string Car::getBrand()const {
return brand;
}
string Car::getMoedl()const {
return model;
}
int Car::getPrice()const {
return price;
}
unsigned int Car::getDistance()const {
return distance;
}
string Car::descripition() const
{
stringstream ret;
ret << "品牌:" << brand << " " << "型号:" << model << " " << "价格:" << price << " "<< "里程:" << distance << " " << "发动机品牌:" << engine->getBrand() << " "<< "发动机型号:" << engine->getModel() << endl;
return ret.str();
}
vector<Tires*> Car::getTires() const
{
return tires;
}
void Car::addTires(Tires& other)
{
tires.push_back(&other);
}
说明:
-
使用**void Tires::inPuttires(vector& tires)**函数时
-
这个函数可以说同时包含了
vector<Tires> Car::getTires() const*
{
return tires;
}void Car::addTires(Tires& other)
{
tires.push_back(&other);
}这两个函数的功能使得最后的返回值都不需要,直接对在主函数中定义的容器进行操作。
-
若这个函数的声明是这样的void Tires::inPuttires vector<Tires*>& tires) 那么在后面使用push_back 函数时
- tires.push_back(&Tires(brand,size,pressure));
这样会出错,&符号要求是一个左值
- Tires tires1(brand, size, pressure);
tires.push_back(&tires1) 这样的话,由于我们始终都是使用一个tires1来作为载体,传递的始终都是他的地址,那样的话,访问的时候就会出错
-
-
还要注意的是当engine是指针或者实例时而选择箭头后者点号,组合和聚合的注意事项参考文档
-
这里说明一下改进方法:一是把engine改为不是指针,加上默认构造函数;二是Tire不使用容器,直接使用对象数组,这样才能更进一步表明两者是一种组合的方式与Car结合的。
第二种
Tire.h
#pragma once
#include <string>
using namespace std;
class Tire
{
public:
Tire(const string &brand="米其林");
~Tire();
string descripton() const;
string getBrand() const;
float getPressure() const;
private:
string brand;
float pressure;
};
Tire.cpp
#include "Tire.h"
#include <sstream>
Tire::Tire(const string &brand)
{
this->brand = brand;
this->pressure = 2.5;
}
Tire::~Tire()
{
}
string Tire::descripton() const
{
stringstream ret;
ret << "品牌:" << brand << "-胎压:" << pressure;
return ret.str();
}
string Tire::getBrand() const
{
return brand;
}
float Tire::getPressure() const
{
return pressure;
}
Engine.h
#pragma once
#include <string>
using namespace std;
class Engine
{
public:
Engine();
Engine(const string &brand, float version);
~Engine();
string description() const;
private:
string brand;
float version;
};
Engine.cpp
#include <sstream>
#include "Engine.h"
Engine::Engine()
{
}
Engine::Engine(const string & brand, float version)
{
this->brand = brand;
this->version = version;
}
Engine::~Engine()
{
}
string Engine::description() const
{
stringstream ret;
ret << "品牌:" << brand << "-型号:" << version;
return ret.str();
}
Car.h
#pragma once
#include <string>
#include "Engine.h"
#include "Tire.h"
using namespace std;
class Car
{
public:
Car();
Car(const string &carBrand, const string &carVer, int carPrice,
const string &engineBrand, float engineVer,
const string &tireBrand = "米其林");
~Car();
Engine getEngine();
Tire* getTire(int i);
string getBrand();
string getVersion();
int getPrice();
int getMiles();
string description();
private:
Engine engine;
Tire tires[4];
string brand; //品牌
string version; //型号
int price;
int miles;
};
Car.cpp
#include <sstream>
#include "Car.h"
Car::Car()
{
}
Car::Car(const string & carBrand, const string & carVer, int carPrice,
const string & engineBrand, float engineVer,
const string & tireBrand):
engine(engineBrand, engineVer), tires{
tireBrand, tireBrand, tireBrand, tireBrand }
{
this->brand = carBrand;
this->price = carPrice;
this->version = carVer;
this->miles = 0;
}
Car::~Car()
{
}
Engine Car::getEngine()
{
return engine;
}
Tire* Car::getTire(int i)
{
if (i>=1 && i<=4) {
return &tires[i];
}
return NULL;
}
string Car::getBrand()
{
return brand;
}
string Car::getVersion()
{
return version;
}
int Car::getPrice()
{
return price;
}
int Car::getMiles()
{
return miles;
}
string Car::description()
{
stringstream ret;
ret << "汽车品牌:" << brand << "-" << version << "-$" << price
<< "\t\t引擎:" << engine.description()
<< "\t\t轮胎:" << tires[0].descripton();
return ret.str();
}
main.cpp
#include <iostream>
#include <Windows.h>
#include "Car.h"
int main(void) {
{
Car car("宝马", "X7", 950000, "宝马", 3.5);
cout << car.description() << endl;
}
system("pause");
return 0;
说明:
-
这里的 Engine 和 Tire 都要使用组合的方式,所以第一种的方式有待改进
-
在 Engine 和 Tire 中都定义一个description函数的目的是在后面Car的description函数中不需要一个一个的调用获取函数,只需要一次即可
-
由于在Car函数中的定义是Tire tires[4] 所以在初始化列表中需要的操作不一样:
Car::Car(const string & carBrand, const string & carVer, int carPrice,
const string & engineBrand, float engineVer,
const string & tireBrand):
engine(engineBrand, engineVer), tires{ tireBrand, tireBrand, tireBrand, tireBrand }根据类比,如果Tire需要多个参数,那么需要在外面加一个括号。