C++ 和使用组合创建对象的一些指导
Some guidance with C++ and creating objects using composition
基本上我的问题是构图。道理我都懂了,但是其中一个测试执行起来很吃力
根据下面的 Computer
和 Monitor
的代码,我必须创建一个最终的 class Complect
,它将有自己的名称,即计算机的名称,显示器的名称,以及将由 price()
函数组成的价格。
Computer.h
#ifndef COMPUTER_H
#define COMPUTER_H
#include <string>
class Computer{
public:
Computer(std::string name, int ram, double price);
std::string name() const;
int ram() const;
double price() const;
void printComputer() const;
void setComputer(std::string name, int ram, double price);
private:
std::string its_name;
int ram_gb;
double cost_price;
};
#endif // COMPUTER_H
Computer.cpp
#include "Computer.h"
#include <iostream>
Computer::Computer(std::string name, int ram, double price)
: its_name(name), ram_gb(ram), cost_price(price){
}
std::string Computer::name() const {
return its_name;
}
int Computer::ram() const {
return ram_gb;
}
double Computer::price() const {
return cost_price;
}
void Computer::printComputer() const{
std::cout << "Computer name = " <<name() <<"\n"
<< "Computer RAM = " <<ram() <<" GB\n"
<< "Computer Price = " << price() <<" EUR \n";
}
Monitor.h
#ifndef MONITOR_H
#define MONITOR_H
#include <string>
class Monitor{
public:
Monitor(std::string name, std::string type, double price);
std::string name() const;
std::string type() const;
double price() const;
//print computer
void printMonitor() const;
//set computer
void setMonitor(std::string name, std::string type, double price);
private:
std::string its_name;
std::string type_set;
double cost_price;
};
#endif // MONITOR_H
Monitor.cpp
#include "Monitor.h"
#include <iostream>
Monitor::Monitor(std::string name, std::string type, double price) : its_name(name), type_set(type), cost_price(price){
}
std::string Monitor::name() const {
return its_name;
}
std::string Monitor::type() const{
return type_set;
}
double Monitor::price() const {
return cost_price;
}
void Monitor::printMonitor() const{
std::cout << "Monitor name = " <<name() <<"\n"
<< "Monitor type = " <<type() <<"\n"
<< "Monitor price = " << price() <<" EUR \n";
}
这是我制作的class:
Complect.h
#ifndef COMPLECT_H
#define COMPLECT_H
#include <string>
class Complect{
public:
Complect(std::string name, std::string computername, std::string monitorname, double price);
std::string name() const;
std::string computername() const;
std::string monitorname() const;
double price() const;
void printComplect();
void setComplect(std::string name, std::string computername, std::string monitorname, double price);
private:
std::string complect_name;
std::string computername_final;
std::string monitorname_final;
double cost_price;
};
#endif // COMPLECT_H
Complect.cpp
#include "Complect.h"
#include "Monitor.h"
#include "Computer.h"
#include <iostream>
Complect::Complect(std::string name, std::string computername, std::string monitorname, double price) :
complect_name(name), computername_final(computername), monitorname_final(monitorname), cost_price(price){
}
std::string Complect::name() const{
return complect_name;
}
std::string Complect::computername() const{
return computername_final;
}
std::string Complect::monitorname() const{
return monitorname_final;
}
double Complect::price() const{
return cost_price;
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " <<computername() <<"\n"
<<"Monitor name = " <<monitorname() <<"\n"
<<"Complect price = " <<price() <<" EUR \n";
}
下面是我在 Main.cpp
中使用 classes 的方法
#include <iostream>
#include "Computer.h"
#include "Monitor.h"
#include "Complect.h"
int main(){
Computer asus("Asus One", 8, 545.95) ;
asus.printComputer() ;
std::cout << "\n";
Monitor iiyama("Iiyama Blackhawk 27inch", "LED", 299.99);
iiyama.printMonitor();
std::cout <<"\n";
Complect numberOne ("Number one complect", asus.name(), iiyama.name(), iiyama.price() + asus.price());
numberOne.printComplect();
std::cout <<"\n";
system ("pause");
return 0;
}
最终结果是应该的,所以这段代码有效。
但问题在于它的结构不正确。
在 main.cpp
文件中,您将看到正在创建 Complect
对象。但我目前在 main.cpp
文件中提供了该对象的所有构造信息。
抱歉,代码有点乱,但我正在努力解决这个问题,目前正在努力......如何让 complect.cpp
文件中的 class 提供自己的所有信息?
目前您不使用组合,而是从另外两个 类 复制属性,并且您在调用 main
的构造函数时做了大量工作
您的代码的第一个小改动是在构造函数的参数中获取 Computer 和 Monitor 的实例:
Complect(std::string name, const Computer &, const Monitor &);
当然,最终价格也在该构造函数中计算,在 main 中,您只需创建一个 Complect 及其名称和部分:
Complect numberOne ("Number one complect", asus, iiyama);
现在 main 幸运的是不必知道价格是如何计算的,否则想象一下如果公式发生变化并且您必须更新构造函数的所有调用:-(。价格的计算方式仅由 Complect.
负责
Complect numberOne ("Number one complect", asus, iiyama);
以上的构造函数setComplect必须更新接收价格,显示器和电脑分开也是一样的道理。
void setComplect(std::string name, std::string computername, std::string monitorname, double computerprice, double monitorprice);
或者用方法
替换它可能更好
void setname(std::string name);
void setcomputer(std::string computername, double computerprice);
void setmonitor(std::string monitorname, double monitorprice);
但是在Complect中复制Computer和Monitor的所有属性是不切实际的,并且您没有对实例的组合。第一种可能性是保存它们的副本:
class Complect{
...
private:
Computer computer;
Monitor monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
std::string Complect::computername() const{
return computer.name();
}
std::string Complect::monitorname() const{
return monitor.name();
}
double Complect::price() const{
return computer.price() + monitor.price();
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " << computer.name() <<"\n"
<<"Monitor name = " << monitor.name() <<"\n"
<<"Complect price = " << price() <<" EUR \n";
}
该解决方案的优点是,如果 Monitor 和 Computer 的初始实例消失,您不会受到影响。缺点是,如果克隆零件之一的价格发生变化,则价格不会更新,除非调用 setXXX
另一种方法是不克隆监视器和计算机,但你不能只克隆它:
class Complect{
...
private:
Computer & computer;
Monitor & monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
因为这假设 Monitor 和 Computer 的实例仍然存在,而 Complect[=57 的对应实例=]存在
幸运的是,C++ 提供了一些有趣的功能来管理它
基本上我的问题是构图。道理我都懂了,但是其中一个测试执行起来很吃力
根据下面的 Computer
和 Monitor
的代码,我必须创建一个最终的 class Complect
,它将有自己的名称,即计算机的名称,显示器的名称,以及将由 price()
函数组成的价格。
Computer.h
#ifndef COMPUTER_H
#define COMPUTER_H
#include <string>
class Computer{
public:
Computer(std::string name, int ram, double price);
std::string name() const;
int ram() const;
double price() const;
void printComputer() const;
void setComputer(std::string name, int ram, double price);
private:
std::string its_name;
int ram_gb;
double cost_price;
};
#endif // COMPUTER_H
Computer.cpp
#include "Computer.h"
#include <iostream>
Computer::Computer(std::string name, int ram, double price)
: its_name(name), ram_gb(ram), cost_price(price){
}
std::string Computer::name() const {
return its_name;
}
int Computer::ram() const {
return ram_gb;
}
double Computer::price() const {
return cost_price;
}
void Computer::printComputer() const{
std::cout << "Computer name = " <<name() <<"\n"
<< "Computer RAM = " <<ram() <<" GB\n"
<< "Computer Price = " << price() <<" EUR \n";
}
Monitor.h
#ifndef MONITOR_H
#define MONITOR_H
#include <string>
class Monitor{
public:
Monitor(std::string name, std::string type, double price);
std::string name() const;
std::string type() const;
double price() const;
//print computer
void printMonitor() const;
//set computer
void setMonitor(std::string name, std::string type, double price);
private:
std::string its_name;
std::string type_set;
double cost_price;
};
#endif // MONITOR_H
Monitor.cpp
#include "Monitor.h"
#include <iostream>
Monitor::Monitor(std::string name, std::string type, double price) : its_name(name), type_set(type), cost_price(price){
}
std::string Monitor::name() const {
return its_name;
}
std::string Monitor::type() const{
return type_set;
}
double Monitor::price() const {
return cost_price;
}
void Monitor::printMonitor() const{
std::cout << "Monitor name = " <<name() <<"\n"
<< "Monitor type = " <<type() <<"\n"
<< "Monitor price = " << price() <<" EUR \n";
}
这是我制作的class:
Complect.h
#ifndef COMPLECT_H
#define COMPLECT_H
#include <string>
class Complect{
public:
Complect(std::string name, std::string computername, std::string monitorname, double price);
std::string name() const;
std::string computername() const;
std::string monitorname() const;
double price() const;
void printComplect();
void setComplect(std::string name, std::string computername, std::string monitorname, double price);
private:
std::string complect_name;
std::string computername_final;
std::string monitorname_final;
double cost_price;
};
#endif // COMPLECT_H
Complect.cpp
#include "Complect.h"
#include "Monitor.h"
#include "Computer.h"
#include <iostream>
Complect::Complect(std::string name, std::string computername, std::string monitorname, double price) :
complect_name(name), computername_final(computername), monitorname_final(monitorname), cost_price(price){
}
std::string Complect::name() const{
return complect_name;
}
std::string Complect::computername() const{
return computername_final;
}
std::string Complect::monitorname() const{
return monitorname_final;
}
double Complect::price() const{
return cost_price;
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " <<computername() <<"\n"
<<"Monitor name = " <<monitorname() <<"\n"
<<"Complect price = " <<price() <<" EUR \n";
}
下面是我在 Main.cpp
中使用 classes 的方法#include <iostream>
#include "Computer.h"
#include "Monitor.h"
#include "Complect.h"
int main(){
Computer asus("Asus One", 8, 545.95) ;
asus.printComputer() ;
std::cout << "\n";
Monitor iiyama("Iiyama Blackhawk 27inch", "LED", 299.99);
iiyama.printMonitor();
std::cout <<"\n";
Complect numberOne ("Number one complect", asus.name(), iiyama.name(), iiyama.price() + asus.price());
numberOne.printComplect();
std::cout <<"\n";
system ("pause");
return 0;
}
最终结果是应该的,所以这段代码有效。 但问题在于它的结构不正确。
在 main.cpp
文件中,您将看到正在创建 Complect
对象。但我目前在 main.cpp
文件中提供了该对象的所有构造信息。
抱歉,代码有点乱,但我正在努力解决这个问题,目前正在努力......如何让 complect.cpp
文件中的 class 提供自己的所有信息?
目前您不使用组合,而是从另外两个 类 复制属性,并且您在调用 main
的构造函数时做了大量工作您的代码的第一个小改动是在构造函数的参数中获取 Computer 和 Monitor 的实例:
Complect(std::string name, const Computer &, const Monitor &);
当然,最终价格也在该构造函数中计算,在 main 中,您只需创建一个 Complect 及其名称和部分:
Complect numberOne ("Number one complect", asus, iiyama);
现在 main 幸运的是不必知道价格是如何计算的,否则想象一下如果公式发生变化并且您必须更新构造函数的所有调用:-(。价格的计算方式仅由 Complect.
负责Complect numberOne ("Number one complect", asus, iiyama);
以上的构造函数setComplect必须更新接收价格,显示器和电脑分开也是一样的道理。
void setComplect(std::string name, std::string computername, std::string monitorname, double computerprice, double monitorprice);
或者用方法
替换它可能更好void setname(std::string name);
void setcomputer(std::string computername, double computerprice);
void setmonitor(std::string monitorname, double monitorprice);
但是在Complect中复制Computer和Monitor的所有属性是不切实际的,并且您没有对实例的组合。第一种可能性是保存它们的副本:
class Complect{
...
private:
Computer computer;
Monitor monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
std::string Complect::computername() const{
return computer.name();
}
std::string Complect::monitorname() const{
return monitor.name();
}
double Complect::price() const{
return computer.price() + monitor.price();
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " << computer.name() <<"\n"
<<"Monitor name = " << monitor.name() <<"\n"
<<"Complect price = " << price() <<" EUR \n";
}
该解决方案的优点是,如果 Monitor 和 Computer 的初始实例消失,您不会受到影响。缺点是,如果克隆零件之一的价格发生变化,则价格不会更新,除非调用 setXXX
另一种方法是不克隆监视器和计算机,但你不能只克隆它:
class Complect{
...
private:
Computer & computer;
Monitor & monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
因为这假设 Monitor 和 Computer 的实例仍然存在,而 Complect[=57 的对应实例=]存在
幸运的是,C++ 提供了一些有趣的功能来管理它