这是将抽象类与OO方法一起使用的正确方法吗?
Is this a correct approach of using abstract classes with an OO approach?
假设我们有 2 个类 A 和 B。两者都是超类 C 的子类。现在让我们假设 C 定义了一个方法 areYouA((,这是一个询问对象是否是 A 类对象的方法。
因此,在 c++ 中,可能的代码是:
C object1 = A()
C object2 = B()
if (object1.areYouA()==true){//crazy code here regarding if it's an A object}
if (object2.areYouA()==false){//crazy code here regarding if it's a B object}
从 OO POV 中,向 B 和 C 类添加一个方法以询问它们各自的对象是否属于 A 类是否正确???如果不正确,那么还有什么方法可以解决这个问题呢????我的目标很明显,我需要 2 个类 A 和 B,在某些时候我有部分二进制数据可能是 A 类或 B 类,而且一个对象最初是 A 类,当它变满时,它的结构需要改变,还有一些行为, 因此成为 B 类的对象。因此,我的方法是将抽象类视为父类,最初声明一个 C 对象但存储一个 A 对象,然后在它发生变化时存储一个 B 对象。这还有别的吗,比如模式???
附加信息:
我想我对此不是很清楚。假设我想将来自 A 对象的信息存储在文件 1 中,将来自 B 对象的信息存储在文件 2 中。如果使用其母类作为接口,那么我如何判断它是 A 对象还是 B 对象以存储在各自的文件中?我是否应该为每个对象的文件名添加贡品,因为它们也属于它们???这意味着如果我需要更改文件名,那么每个对象也需要更改。
正确的方法是使用虚函数来实现多态行为:
struct C
{
virtual void do_crazy_stuff() { } // (see text below)
virtual ~C() { } // always have a virtual d'tor for polymorphic bases
};
struct A : C
{
virtual void do_crazy_stuff() { /* your crazy code for A */ }
};
struct B : C
{
virtual void do_crazy_stuff() { /* your crazy code for B */ }
};
现在您可以在任何地方使用相同的界面:
void process_data(C & x) // <-- Note: take argument by reference!!
{
x.do_crazy_stuff();
}
这适用于派生自C
类型的任何对象:
int main()
{
A x;
B y;
process_data(x); // calls x.A::do_crazy_stuff
process_data(y); // calls x.B::do_crazy_stuff
}
如果你愿意,你甚至可以将基函数C::do_crazy_stuff
声明为纯虚拟函数;这使得基类抽象(因此它不能被实例化(。
首先,
C object1 = A();
C object2 = B();
对对象进行切片。它们不再是A
型或B
型,而是C
。
你可以为此使用指针:
C* object1 = new A();
C* object2 = new B();
尽管C
指针,但它们分别指向A
和B
的实例。
第二,你的方法是错误的。您似乎没有利用多态性。如果您有在类之间共享的功能,则应在 C
中实现。如果它发生了变化,您应该有virtual
方法。
关于对象类型的知识通常至少是一种代码气味。只需使用多态性即可更改行为。尽管如果确实有必要,正确的方法是使用dynamic_cast
:
C* object1 = new A();
A* pA = dynamic_cast<A*>(object1);
如果object1
不指向类型为 A
的对象,则将NULL
pA
。
在我看来,这是一个设计问题,你必须更好地分析你的问题。为什么需要知道对象的类型?为什么你不在 A 和 B 类中实现接口方法,它将对二进制数据做你需要的任何操作?查看访客设计模式,以获取如何以这种方式实现它的图像。
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 出于什么目的,非虚拟方法将与C++一起使用?
- 如何在Visual Studio 2017上将类方法设置为参数并将它们与lambda一起使用?
- 将派生类方法与基类unique_ptr一起使用
- 让类与运算符一起工作更简单的方法
- 将赋值运算符与make_pair方法一起使用会生成 CLion 警告
- 有没有一种干净(更)的方法将 CRTP 与可变参数继承混合在一起?
- 与其所有者一起分配阵列的正确方法
- 将方法与模板一起使用
- 有没有一种方法可以将QVariant与QVector一起使用
- 如何将策略模式与派生类中的其他方法一起使用
- 有什么方法可以将字符串文字u8与变量一起使用吗
- 有没有一种方法可以将升压信号和插槽与不可复制的对象一起使用
- 具有与专用列表一起使用的参数列表的超类方法<superclass>
- 为什么将我的打印方法与std::cout一起使用会导致错误
- C++ 继承函数指针,可与派生方法一起使用
- 为什么点运算符(.)可以与私有类成员/方法一起使用
- 将 boost::function 与实例方法一起使用
- 这是将抽象类与OO方法一起使用的正确方法吗?
- 将SWIG与以std::string为参数的方法一起使用