如何使用模块化架构避免重复功能
How to avoid duplicating functions with a modular architecture
我正在尝试使用 C++ 实现模块化架构,其中每个 .cpp
文件都有一个 .h
文件。这些文件目前只有空函数:
cycle.h
#include <iostream>
#ifndef CYCLIST_H
#define CYCLIST_H
#pragma once
class cyclist{
private:
double width;
double length;
int helment;
public:
void Predict();
double get_width();
double get_length();
int get_helmet();
};
#endif
cycle.cpp
#include <iostream>
#include "cyclist.h"
void cyclist::Predict(){std::cout << "Predict something!" << std::endl;}
double cyclist::get_width(){}
double cyclist::get_length(){}
int cyclist::get_helmet(){}
vehicle.h
#include <iostream>
#ifndef VEHICLE_H
#define VEHICLE_H
#pragma once
class vehicle{
private:
double width;
double length;
int number_of_doors;
public:
void Predict();
double get_width();
double get_length();
int get_number();
};
#endif
vehicle.cpp
#include <iostream>
#include "vehicle.h"
void vehicle::Predict(){std::cout << "Predict something!" << std::endl;}
double vehicle::get_width(){}
double vehicle::get_length(){}
int vehicle::get_number(){}
如您所见,我重复了 get_wdith()
、get_height()
和 Predict()
函数。原因是他们每个人都会有相同功能的不同实现。
如何从基数 class 中导出所有这些函数?如果我使用基础 class、would/can 我仍然使用 .h
个文件?
编辑
所以我创建的是一个单独的头文件Base.h,如下所示:
#include <iostream>
#pragma once
class Base{
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
virtual int get_number_of_doors() = 0;
virtual bool get_helmet_state();
};
然后我决定像这样从自行车手和车辆 class 继承这些:
cyclist.cpp
#include <iostream>
#include "Base.h"
void Base::Predict(){std::cout << "Predict something!" << std::endl;}
double Base::get_width(){return 0;}
double Base::get_length(){return 0;}
bool Base::get_helmet_state(){return true;}
vehicle.cpp
#include <iostream>
#include "Base.h"
void Base::Predict(){std::cout << "Predict something!" << std::endl;};
double Base::get_width(){return 0;}
double Base::get_length(){return 0;}
int Base::get_number_of_doors(){return 0;}
现在,当我 运行 它时,我收到一条错误消息,指出 Base::Predict()
有多个定义。此功能将在每个 class 中以不同的方式实现。我尝试添加 override
关键字,但它不允许。
第一步:应用 Liskov Substitution Principle 以确保继承有意义。
步骤One-A:确保Composition isn't a better fit。
第二步:制作基地 class
class Base // For demonstration purposes only. Give this a more descriptive name in your code
{
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
};
如果你愿意,可以在自己的 header 中弹出它。没有什么可以阻止继承层次结构的使用和划分为 headers.
取决于你的用例,you may or may not need the destructor,但如果你正在学习 C++,让你的生活更轻松并把它放进去。拥有它可能会在运行时浪费一些时间,但你会遇到更少的怪事如果您的经验不足导致您误入歧途,则必须调试的问题。
您要覆盖的所有函数都必须声明 virtual
. virtual
is sticky, so you don't have to keep repeating it in the derived classes, but keep an eye out for final
。
virtual
末尾的 = 0
函数 makes them pure 并使 class 抽象。这可能是也可能不是您想要的行为,但它们中的每一个都有不同的实现 强烈暗示它是。阅读链接文档以确保确定。
第三步:继承
class cyclist: public Base{
private:
double width;
double length;
int helment;
public:
void Predict() override;
double get_width() override;
double get_length() override;
int get_helmet();
};
请注意,override
keyword 不是硬性要求,但它可以通过剔除错误为您省去很多麻烦,只需几秒钟即可键入,编译时间微不足道,并且在运行时绝对没有。世界上有几种 win-win 情况,所以要好好利用这一点。
附录:
如果您在覆盖函数中的 class 之间共享行为,请考虑将共享行为的代码移动到 protected
支持函数中,并从覆盖函数中调用支持函数以消除重复。
class Base // For demonstration purposes only. Give this a more descriptive name in your code
{
protected:
double predict_support();
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
};
以后 Base.cpp
double Base::predict_support()
{
return do_complicated_math();
}
然后像
一样使用它
void cyclist::Predict()
{
std::cout << "Predict something: " << predict_support() << std::endl;
}
我正在尝试使用 C++ 实现模块化架构,其中每个 .cpp
文件都有一个 .h
文件。这些文件目前只有空函数:
cycle.h
#include <iostream>
#ifndef CYCLIST_H
#define CYCLIST_H
#pragma once
class cyclist{
private:
double width;
double length;
int helment;
public:
void Predict();
double get_width();
double get_length();
int get_helmet();
};
#endif
cycle.cpp
#include <iostream>
#include "cyclist.h"
void cyclist::Predict(){std::cout << "Predict something!" << std::endl;}
double cyclist::get_width(){}
double cyclist::get_length(){}
int cyclist::get_helmet(){}
vehicle.h
#include <iostream>
#ifndef VEHICLE_H
#define VEHICLE_H
#pragma once
class vehicle{
private:
double width;
double length;
int number_of_doors;
public:
void Predict();
double get_width();
double get_length();
int get_number();
};
#endif
vehicle.cpp
#include <iostream>
#include "vehicle.h"
void vehicle::Predict(){std::cout << "Predict something!" << std::endl;}
double vehicle::get_width(){}
double vehicle::get_length(){}
int vehicle::get_number(){}
如您所见,我重复了 get_wdith()
、get_height()
和 Predict()
函数。原因是他们每个人都会有相同功能的不同实现。
如何从基数 class 中导出所有这些函数?如果我使用基础 class、would/can 我仍然使用 .h
个文件?
编辑
所以我创建的是一个单独的头文件Base.h,如下所示:
#include <iostream>
#pragma once
class Base{
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
virtual int get_number_of_doors() = 0;
virtual bool get_helmet_state();
};
然后我决定像这样从自行车手和车辆 class 继承这些:
cyclist.cpp
#include <iostream>
#include "Base.h"
void Base::Predict(){std::cout << "Predict something!" << std::endl;}
double Base::get_width(){return 0;}
double Base::get_length(){return 0;}
bool Base::get_helmet_state(){return true;}
vehicle.cpp
#include <iostream>
#include "Base.h"
void Base::Predict(){std::cout << "Predict something!" << std::endl;};
double Base::get_width(){return 0;}
double Base::get_length(){return 0;}
int Base::get_number_of_doors(){return 0;}
现在,当我 运行 它时,我收到一条错误消息,指出 Base::Predict()
有多个定义。此功能将在每个 class 中以不同的方式实现。我尝试添加 override
关键字,但它不允许。
第一步:应用 Liskov Substitution Principle 以确保继承有意义。
步骤One-A:确保Composition isn't a better fit。
第二步:制作基地 class
class Base // For demonstration purposes only. Give this a more descriptive name in your code
{
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
};
如果你愿意,可以在自己的 header 中弹出它。没有什么可以阻止继承层次结构的使用和划分为 headers.
取决于你的用例,you may or may not need the destructor,但如果你正在学习 C++,让你的生活更轻松并把它放进去。拥有它可能会在运行时浪费一些时间,但你会遇到更少的怪事如果您的经验不足导致您误入歧途,则必须调试的问题。
您要覆盖的所有函数都必须声明 virtual
. virtual
is sticky, so you don't have to keep repeating it in the derived classes, but keep an eye out for final
。
virtual
末尾的 = 0
函数 makes them pure 并使 class 抽象。这可能是也可能不是您想要的行为,但它们中的每一个都有不同的实现 强烈暗示它是。阅读链接文档以确保确定。
第三步:继承
class cyclist: public Base{
private:
double width;
double length;
int helment;
public:
void Predict() override;
double get_width() override;
double get_length() override;
int get_helmet();
};
请注意,override
keyword 不是硬性要求,但它可以通过剔除错误为您省去很多麻烦,只需几秒钟即可键入,编译时间微不足道,并且在运行时绝对没有。世界上有几种 win-win 情况,所以要好好利用这一点。
附录:
如果您在覆盖函数中的 class 之间共享行为,请考虑将共享行为的代码移动到 protected
支持函数中,并从覆盖函数中调用支持函数以消除重复。
class Base // For demonstration purposes only. Give this a more descriptive name in your code
{
protected:
double predict_support();
public:
virtual ~Base() = default;
virtual void Predict() = 0;
virtual double get_width() = 0;
virtual double get_length() = 0;
};
以后 Base.cpp
double Base::predict_support()
{
return do_complicated_math();
}
然后像
一样使用它void cyclist::Predict()
{
std::cout << "Predict something: " << predict_support() << std::endl;
}